Entity Framework ย้อนกลับและลบการโยกย้ายที่ไม่ดี


174

ฉันใช้ EF 6.0 สำหรับโครงการของฉันใน C # ด้วยการโยกย้ายและการปรับปรุงด้วยตนเอง ฉันมีการโยกย้ายประมาณ 5 บนฐานข้อมูล แต่ฉันรู้ว่าการโยกย้ายครั้งสุดท้ายไม่ดีและฉันไม่ต้องการ ฉันรู้ว่าฉันสามารถย้อนกลับไปยังการโยกย้ายครั้งก่อนได้ แต่เมื่อฉันเพิ่มการโยกย้าย (คงที่) ใหม่และเรียกใช้ Update-Database แม้แต่การโยกย้ายที่ไม่ดีก็ถูกนำไปใช้

ฉันพยายามย้อนกลับการโยกย้ายครั้งก่อนและลบไฟล์ด้วยการโยกย้ายที่ไม่ดี แต่เมื่อฉันพยายามเพิ่มการย้ายข้อมูลใหม่ฉันได้รับข้อผิดพลาดเมื่ออัปเดตฐานข้อมูลเนื่องจากไฟล์การโยกย้ายเสียหาย (โดยเฉพาะอย่างยิ่งรหัสบรรทัดแรกเปลี่ยนชื่อตาราง A เป็น B และเป็นบรรทัดถัดไป EF พยายามอัปเดตตารางด้วย ชื่อ A - อาจเป็นข้อบกพร่องของ EF)

มีคำถามที่ฉันสามารถเรียกใช้ซึ่งจะบอก EF ว่า "ลืมการย้ายข้อมูลครั้งล่าสุดแบบที่ไม่เคยมีมาหรือไม่เลว" สิ่งที่ต้องการลบการโยกย้าย

Edit1 ฉันพบวิธีแก้ปัญหาที่เหมาะสมสำหรับฉัน เปลี่ยนโมเดลให้อยู่ในสภาพดีและวิ่งAdd-Migration TheBadMigration -Forceได้ การดำเนินการนี้จะนำไปสู่การนั่งร้านใหม่ไม่ใช่การย้ายที่ใช้

อย่างไรก็ตามเรื่องนี้ยังไม่สามารถตอบคำถามเดิมได้อย่างสมบูรณ์ หากฉันอัปเดตฐานข้อมูลไปยังการโยกย้ายที่ไม่ดีฉันไม่พบวิธีที่ดีในการย้อนกลับและสร้างการย้ายข้อมูลใหม่ไม่รวมถึงการย้ายที่ไม่ดี

ขอบคุณ


ฉันต้องรีสตาร์ท Visual Studio จากนั้นมันก็เริ่มทำงานอย่างถูกต้อง สิ่งนี้เกิดขึ้นกับฉันสองสามครั้งแล้วหลังจากที่ยุ่งกับการย้ายข้อมูลโดยไม่ต้องอัปเดตฐานข้อมูลจริง
Andrei Dvoynos

คำตอบ:


167

คุณมี 2 ตัวเลือก:

  • คุณสามารถลงจากการโยกย้ายที่ไม่ดีและนำไปใช้ในการโยกย้ายใหม่ (คุณจะต้องทำการเปลี่ยนแปลงที่ตามมากับโมเดล) นี่เป็นเวอร์ชันที่ดีกว่า

    ฉันใช้ตัวเลือกนี้กับสิ่งต่าง ๆ ที่ไปหลายสภาพแวดล้อม

  • ตัวเลือกอื่นคือการทำงานUpdate-Database –TargetMigration: TheLastGoodMigrationกับฐานข้อมูลที่ถูกปรับใช้ของคุณแล้วลบการโยกย้ายออกจากโซลูชันของคุณ นี่เป็นทางเลือกที่ hulk smash และต้องการให้ดำเนินการกับฐานข้อมูลใด ๆ ที่ปรับใช้กับเวอร์ชันที่ไม่ดี

    หมายเหตุ:เพื่อ rescaffold Add-Migration [existingname] -Forceโยกย้ายคุณสามารถใช้ อย่างไรก็ตามสิ่งนี้จะเขียนทับการโยกย้ายที่มีอยู่ของคุณดังนั้นโปรดทำเช่นนี้เฉพาะในกรณีที่คุณลบการโยกย้ายที่มีอยู่ออกจากฐานข้อมูล สิ่งนี้ทำเช่นเดียวกับการลบไฟล์การย้ายข้อมูลที่มีอยู่และทำงานอยู่add-migration

    ฉันใช้ตัวเลือกนี้ในขณะที่กำลังพัฒนา


1
ตัวเลือก smash hulk ไม่ทำงาน ฉันยังไม่ได้ใช้การโยกย้ายที่ไม่ดีกับฐานข้อมูล ฉันพยายาม แต่มันใช้งานไม่ได้เพราะชื่อตารางที่ฉันระบุไว้ในคำถามเดิม ตัวเลือกแรกที่ฉันไม่ชอบมากเพราะดูเหมือนว่าฉันจะต้องเปลี่ยนรหัสการโยกย้าย ถ้าฉันทำมันไม่ดีฉันสามารถทำลายมันได้ทั้งหมด
Martin Brabec

8
หากคุณยังไม่ได้ใช้การโยกย้ายที่ไม่ดีไม่มีอะไรหยุดคุณก็สามารถลบมันและ rescaffolding หรือแก้ไขการโยกย้ายที่ขาด
ไม่รัก

4
คำตอบ 'hulk smash' เป็นคำตอบสำหรับฉันเมื่อพัฒนาและฉันต้องการเพิ่มบางสิ่งบางอย่างในการย้ายถิ่นที่ฉันพลาด ผมคิดว่าเหตุผลที่มันไม่ได้ทำงานให้กับมาร์ตินที่ไม่เกี่ยวข้องกัน (หรืออาจจะเกี่ยวข้องกับการเปลี่ยนแปลงคีมาฐานข้อมูลด้วยตนเอง)
rethenhouser2

1
@ BenRethmeier เป็นกฎทั่วไปฉันใช้ตัวเลือก smash hulk เฉพาะในขณะที่ฉันกำลังพัฒนา ในกระทุ้งฉันจะสร้างการโยกย้ายใหม่เพื่อแก้ไขปัญหา เหตุผลก็คือคุณต้องมีการจัดการด้วยตนเองหากคุณกำลังลดระดับฐานข้อมูล ฉันไม่ชอบสิ่งใดที่ต้องการการแทรกแซงด้วยตนเองในผลิตภัณฑ์
ไม่ได้รัก

1
HULK SMASH !!!! --- ฉันพยายามเป็นคนดี แต่ EF ไม่ได้เล่น - ฉันกลับไปเป็นคนสุดท้ายที่รู้จัก - (สำรองไฟล์การโยกย้าย) ลบการโยกย้ายที่เพิ่มเข้ามา - บังคับ - เปลี่ยนชื่อเป็นก่อนหน้าและคัดลอกรหัสฐานข้อมูลอัพเดทแล้ว การโยกย้ายครั้งที่สองในลักษณะเดียวกัน - ไม่มีข้อผิดพลาด - กลับสู่ปกติ
Traci

127

ตามที่คำถามระบุว่าสิ่งนี้นำไปใช้กับการโยกย้ายในสภาพแวดล้อมประเภทการพัฒนาที่ยังไม่ได้เผยแพร่

ปัญหานี้สามารถแก้ไขได้ในขั้นตอนเหล่านี้: กู้คืนฐานข้อมูลของคุณไปยังการโยกย้ายที่ดีครั้งล่าสุดลบการโยกย้ายที่ไม่ดีออกจากโครงการ Entity Framework ของคุณสร้างการโยกย้ายใหม่และนำไปใช้กับฐานข้อมูล หมายเหตุ: การตัดสินจากความคิดเห็นคำสั่งที่แน่นอนเหล่านี้อาจไม่สามารถใช้งานได้อีกต่อไปหากคุณใช้ EF Core

ขั้นตอนที่ 1: คืนค่าเป็นการโยกย้ายก่อนหน้า

หากคุณยังไม่ได้ใช้การย้ายข้อมูลคุณสามารถข้ามส่วนนี้ได้ หากต้องการคืนค่าสคีมาฐานข้อมูลของคุณให้เป็นประเด็นก่อนหน้านี้คำสั่ง Update-Database พร้อมกับ -TargetMigration ตัวเลือกระบุการโยกย้ายที่ดีครั้งสุดท้าย หากรหัสเฟรมเวิร์กเอนทิตีของคุณอยู่ในโครงการอื่นในโซลูชันของคุณคุณอาจต้องใช้ตัวเลือก '-Project' หรือสลับโครงการเริ่มต้นในคอนโซลตัวจัดการแพคเกจ

Update-Database TargetMigration: <name of last good migration>

ในการรับชื่อของการโยกย้ายที่ดีครั้งสุดท้ายให้ใช้คำสั่ง 'Get-Migrations' เพื่อดึงรายชื่อการย้ายข้อมูลที่ใช้กับฐานข้อมูลของคุณ

PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
201508242303096_Bad_Migration
201508211842590_The_Migration_applied_before_it
201508211440252_And_another

รายการนี้แสดงการย้ายถิ่นที่ใช้ล่าสุดก่อน เลือกการย้ายข้อมูลที่เกิดขึ้นในรายการหลังจากรายการที่คุณต้องการปรับลดรุ่นเป็นรายการที่นำไปใช้ก่อนรายการที่คุณต้องการปรับลดรุ่น ตอนนี้ออกฐานข้อมูลการปรับปรุง

Update-Database TargetMigration: "<the migration applied before it>"

การย้ายข้อมูลทั้งหมดที่ใช้หลังจากที่ระบุจะถูกลดระดับเพื่อเริ่มต้นด้วยการโยกย้ายล่าสุดที่ใช้ครั้งแรก

ขั้นตอนที่ 2: ลบการย้ายข้อมูลของคุณออกจากโครงการ

remove-migration name_of_bad_migration

หากremove-migrationคำสั่งไม่พร้อมใช้งานใน Entity Framework เวอร์ชันของคุณให้ลบไฟล์ของการโยกย้ายโฟลเดอร์ 'Migrations' โครงการ EF ของคุณด้วยตนเอง ณ จุดนี้คุณมีอิสระในการสร้างการย้ายข้อมูลใหม่และนำไปใช้กับฐานข้อมูล

ขั้นตอนที่ 3: เพิ่มการย้ายข้อมูลใหม่ของคุณ

add-migration my_new_migration

ขั้นตอนที่ 4: ใช้การย้ายข้อมูลของคุณกับฐานข้อมูล

update-database

6
ด้วย EF Core ดูเหมือนว่า Get-Migrations ได้ถูกลบไปแล้ว
Kevin Burton

1
ขั้นตอนที่ 2 ! - คุณสมบัติที่มีประโยชน์มาก ตามที่ @KevinBurton พูดถึง และแล้ว add-migration "new migration",update-database
อเล็กซานเด Frolov

2
-migration ปรับปรุงฐานข้อมูล: "<โยกย้ายนำไปใช้ก่อนที่จะ>" @ David Sopko
Fuat

ขอบคุณ @AlexanderFrolov ฉันอัปเดตโซลูชันเพื่อแสดงความคิดเห็นของคุณ
David Sopko

1
เราจำเป็นต้องใช้การย้ายข้อมูลหลังจากขั้นตอนที่ 2
Rahul

55

สำหรับผู้ที่ใช้EF Core กับ ASP.NET Core v1.0.0ฉันมีปัญหาคล้ายกันและใช้คำสั่งต่อไปนี้เพื่อแก้ไข(โพสต์ของ @ DavidSopko ชี้ให้ฉันไปในทิศทางที่ถูกต้อง แต่รายละเอียดแตกต่างกันเล็กน้อยสำหรับ EF Core) :

Update-Database <Name of last good migration>
Remove-Migration

ตัวอย่างเช่นในการพัฒนาปัจจุบันของฉันคำสั่งกลายเป็น

PM> Update-Database CreateInitialDatabase
Done.
PM> Remove-Migration
Done.
PM> 

การย้ายย้ายจะลบการโยกย้ายครั้งสุดท้ายที่คุณใช้ หากคุณมีสถานการณ์ที่ซับซ้อนมากขึ้นที่มีการย้ายหลายรายการที่จะลบ (ฉันมีเพียง 2 รายการเริ่มต้นและไม่ดี) ฉันขอแนะนำให้คุณทดสอบขั้นตอนในโครงการจำลอง

ปัจจุบันดูเหมือนจะไม่มีคำสั่ง Get-Migrations ใน EF Core (v1.0.0) ดังนั้นคุณต้องดูในโฟลเดอร์การย้ายข้อมูลของคุณและทำความคุ้นเคยกับสิ่งที่คุณทำ อย่างไรก็ตามมีคำสั่งช่วยเหลือที่ดี:

PM> get-help entityframework

การฟื้นฟู dastabase ใน VS2015 SQL Server Object Explorer ข้อมูลของฉันทั้งหมดได้รับการเก็บรักษาไว้และการย้ายข้อมูลที่ฉันต้องการเปลี่ยนกลับได้หายไป :)

เริ่มแรกฉันลอง Remove-Migration ด้วยตัวเองและพบว่าคำสั่ง error สับสน:

System.InvalidOperationException: การย้ายข้อมูล '... ' ได้ถูกนำไปใช้กับฐานข้อมูลแล้ว นำไปใช้แล้วลองอีกครั้ง หากการย้ายข้อมูลถูกนำไปใช้กับฐานข้อมูลอื่นให้พิจารณาการคืนค่าการเปลี่ยนแปลงโดยใช้การโยกย้ายใหม่

มีข้อเสนอแนะในการปรับปรุงถ้อยคำนี้อยู่แล้ว แต่ฉันต้องการข้อผิดพลาดที่จะพูดแบบนี้:

เรียกใช้ Update-Database (ชื่อการโยกย้ายที่ดีสุดท้าย) เพื่อเปลี่ยน schema ของฐานข้อมูลกลับไปเป็นสถานะนั้น คำสั่งนี้จะทำการย้ายข้อมูลทั้งหมดที่เกิดขึ้นหลังจากการย้ายข้อมูลที่ระบุไปยังฐานข้อมูลอัพเดต จากนั้นคุณสามารถเรียกใช้ Remove-Migration (ชื่อการย้ายเพื่อลบ)

เอาต์พุตจากคำสั่งช่วยเหลือของ EF Core มีดังต่อไปนี้:

 PM> get-help entityframework
                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

TOPIC
    about_EntityFrameworkCore

SHORT DESCRIPTION
    Provides information about Entity Framework Core commands.

LONG DESCRIPTION
    This topic describes the Entity Framework Core commands. See https://docs.efproject.net for information on Entity Framework Core.

    The following Entity Framework cmdlets are included.

        Cmdlet                      Description
        --------------------------  ---------------------------------------------------
        Add-Migration               Adds a new migration.

        Remove-Migration            Removes the last migration.

        Scaffold-DbContext          Scaffolds a DbContext and entity type classes for a specified database.

        Script-Migration            Generates a SQL script from migrations.

        Update-Database             Updates the database to a specified migration.

        Use-DbContext               Sets the default DbContext to use.

SEE ALSO
    Add-Migration
    Remove-Migration
    Scaffold-DbContext
    Script-Migration
    Update-Database
    Use-DbContext

6

คุณยังสามารถใช้

Remove-Migration -Force

การดำเนินการนี้จะย้อนกลับและลบการย้ายข้อมูลที่ใช้ครั้งล่าสุด


4

ก่อนอัปเดตการโยกย้ายที่สมบูรณ์แบบล่าสุดของคุณผ่านคำสั่งนี้:

Update-Database TargetMigration

ตัวอย่าง:

Update-Database -20180906131107_xxxx_xxxx

และจากนั้นลบการย้ายข้อมูลที่ไม่ได้ใช้ด้วยตนเอง


2
ควรเป็น: อัปเดตฐานข้อมูล -TargetMigration 20180906131107_xxxx_xxxx
Elger Mensonides

Update-Database 20180906131107_xxxx_xxxx(ไม่มีเครื่องหมายขีดกลาง) ทำงานให้ฉัน ไม่มีรุ่นของTargetMigrationสวิตช์ที่ใช้งานได้ คำสั่งเหล่านี้ดูเหมือนจะเป็นเป้าหมายที่เคลื่อนที่ได้ (เช่นเปลี่ยนในทุกเวอร์ชั่น)
รวมไม่มี

3

ในฐานะ. NET Core 2.2 TargetMigrationดูเหมือนว่าจะหายไป:

get-help Update-Database

NAME
    Update-Database

SYNOPSIS
    Updates the database to a specified migration.


SYNTAX
    Update-Database [[-Migration] <String>] [-Context <String>] [-Project <String>] [-StartupProject <String>] [<CommonParameters>]


DESCRIPTION
    Updates the database to a specified migration.


RELATED LINKS
    Script-Migration
    about_EntityFrameworkCore 

REMARKS
    To see the examples, type: "get-help Update-Database -examples".
    For more information, type: "get-help Update-Database -detailed".
    For technical information, type: "get-help Update-Database -full".
    For online help, type: "get-help Update-Database -online"

ดังนั้นตอนนี้ใช้งานได้สำหรับฉัน:

Update-Database -Migration 20180906131107_xxxx_xxxx

เช่นเดียวกับ (ไม่มี-Migrationสวิตช์):

Update-Database 20180906131107_xxxx_xxxx

ในบันทึกย่อที่เพิ่มเข้ามาคุณจะไม่สามารถลบโฟลเดอร์การโยกย้ายได้อย่างหมดจดโดยไม่ทำให้ Model Snapshot ของคุณไม่ซิงค์ ดังนั้นหากคุณเรียนรู้วิธีการที่ยากลำบากและจบลงด้วยการโยกย้ายที่ว่างซึ่งคุณรู้ว่าควรมีการเปลี่ยนแปลงคุณสามารถเรียกใช้ (ไม่จำเป็นต้องใช้สวิตช์สำหรับการโยกย้ายครั้งสุดท้าย):

Remove-migration

มันจะทำความสะอาดเป็นระเบียบและนำคุณกลับสู่ที่ที่คุณต้องการแม้ว่าโฟลเดอร์การย้ายข้อมูลครั้งสุดท้ายจะถูกลบด้วยตนเอง


0

สำหรับ EF 6 ต่อไปนี้เป็นหนึ่งในสายการบินหากคุณกำลังพัฒนาอีกครั้งในการพัฒนา เพียงอัปเดต vars จากนั้นใช้ลูกศรขึ้นในคอนโซลตัวจัดการแพคเกจเพื่อล้างและทำซ้ำ

$lastGoodTarget = "OldTargetName"; $newTarget = "NewTargetName"; Update-Database -TargetMigration "$lastGoodTarget" -Verbose; Add-Migration "$newTarget" -Verbose -Force

ทำไมคุณถึงถามถึงสิ่งนี้ ไม่แน่ใจว่าจะใช้ EF6 เวอร์ชันใด แต่หากเป้าหมายการย้ายข้อมูลใหม่ของคุณได้ถูกนำไปใช้แล้วให้ใช้ '-Force' เพื่อนั่งร้านใหม่ใน Add-Migration จริง ๆ แล้วจะไม่ได้นั่งร้านอีก แต่ให้สร้างไฟล์ใหม่แทน แต่เพราะคุณไม่ต้องการเสีย 'Down' ของคุณ) ตัวอย่างด้านบนทำ 'ลง' ก่อนหากจำเป็น - บังคับให้ทำงานได้อย่างถูกต้องในการสร้างโครงร่างใหม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.