Migrasi EF: Kembalikan migrasi yang terakhir diterapkan?


436

Ini terlihat seperti tugas yang sangat umum, tetapi saya tidak dapat menemukan cara mudah untuk melakukannya.

Saya ingin membatalkan migrasi terapan terakhir. Saya akan mengharapkan perintah sederhana, seperti

PM> Update-Database -TargetMigration:"-1"

Alih-alih, yang bisa saya pikirkan hanyalah:

PM> Get-Migrations

Retrieving migrations that have been applied to the target database.
201208012131302_Add-SystemCategory
201207311827468_CategoryIdIsLong
201207232247409_AutomaticMigration
201207211340509_AutomaticMigration
201207200025294_InitialCreate

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

(Setidaknya aku bisa menggunakan nama saja, melewatkan stempel waktu ...)

Apakah ada cara yang lebih mudah?


1
Sedih, di sini kita bertahun-tahun kemudian dan tidak ada yang benar-benar membaca pertanyaan itu.
Daniel ZA

Jawaban:


162

Pada EF 5.0, pendekatan yang Anda gambarkan adalah cara yang disukai. Begitu

PM> Update-Database -TargetMigration:"NameOfSecondToLastMigration"

atau menggunakan contoh migrasi Anda

PM> Update-Database -TargetMigration:"CategoryIdIsLong"

Salah satu solusinya adalah dengan membuat skrip PS wrapper yang mengotomatiskan langkah-langkah di atas. Selain itu, jangan ragu untuk membuat permintaan fitur untuk ini, atau lebih baik lagi, cobalah menerapkannya! https://github.com/dotnet/ef6


4
Detail lain: Jika Anda memiliki Migrasi Manual yang sudah ada, Anda harus memutar kembali, tetapi menyadari metode "Turun" Anda tidak benar-benar mengembalikan hal-hal dengan benar, Anda dapat mengedit dan menyimpannya, kemudian jalankan kembali pembaruan-database -tentang .. hingga gulungan kembali dengan benar. Mengubah Migrasi Manual setelah fakta - setelah Anda sudah menerapkannya - tidak mengubahnya menjadi sesuatu yang tidak boleh diedit.
Chris Moschini

1
Ini tidak bekerja untuk saya. Yang saya dapatkan adalah "migrasi target yang ditentukan" -1 "tidak ada.
tutiplain

2
@tutiplain Lihatlah blok kode keduanya. Anda mengutip apa yang dia inginkan ada, bukan apa yang ada.
Sinjai

apa cara yang benar untuk melakukan ini menggunakan perintah dotnet? Maaf saya tidak dapat menemukan di dokumentasi atau saya kehilangan sesuatu. Sudah mencoba melalui entitasframeworktutorial.net/efcore/... ada saran?
Sijan Shrestha

Saya menemukan solusinya, dotnet ef database update LastGoodMigrationnamun, ini tampaknya membingungkan karena saya berasal dari latar belakang simpul dan menggunakan knex, sequlize, mereka memiliki perintah untuk mengembalikan perubahan terakhir, apakah ada perintah untuk mengembalikan tindakan terakhir yang diterapkan pada database ?
Sijan Shrestha

415

Saya ingin menambahkan beberapa klarifikasi ke utas ini:

Update-Database -TargetMigration:"name_of_migration"

Apa yang Anda lakukan di atas adalah mengatakan bahwa Anda ingin mengembalikan semua migrasi SAMPAI Anda tinggal dengan migrasi yang ditentukan. Jadi, jika Anda menggunakan MENDAPATKAN MIGRASI dan Anda menemukan bahwa Anda memiliki A, B, C, D, dan E, maka menggunakan perintah ini akan mengembalikan E dan D untuk membawa Anda ke C:

Update-Database -TargetMigration:"C"

Juga, kecuali ada yang bisa berkomentar sebaliknya, saya perhatikan bahwa Anda dapat menggunakan nilai ordinal dan pendek -Target beralih (dengan demikian, -Target adalah sama dengan -TargetMigrasi). Jika Anda ingin mengembalikan semua migrasi dan memulai kembali, Anda dapat menggunakan:

Update-Database -Target:0

0, di atas, akan mengembalikan bahkan migrasi PERTAMA ( ini adalah perintah yang merusak - pastikan Anda tahu apa yang Anda lakukan sebelum Anda menggunakannya! ) - sesuatu yang tidak dapat Anda lakukan jika Anda menggunakan sintaks di atas yang memerlukan nama migrasi target (nama migrasi ke-0 tidak ada sebelum migrasi diterapkan!). Jadi dalam hal ini, Anda harus menggunakan nilai 0 (ordinal). Demikian juga, jika Anda telah menerapkan migrasi A, B, C, D, dan E (dalam urutan itu), maka ordinal 1 harus merujuk ke A, ordinal 2 harus merujuk ke B, dan seterusnya. Jadi untuk mengembalikan ke B Anda dapat menggunakan:

Update-Database -TargetMigration:"B"

atau

Update-Database -TargetMigration:2

Edit Oktober 2019:

Menurut jawaban terkait ini pada pertanyaan serupa, perintah yang benar adalah -Targetuntuk EF Core 1.1 sementara -Migrationuntuk EF Core 2.0.


27
Nama migrasi dengan indeks 0 adalah $InitialDatabase.
MEMark

1
Terima kasih. Apakah ada nilai $ (nama) untuk merujuk ke posisi indeks lainnya, seperti $ LatestDatabase, atau sesuatu seperti itu?
Jazimov

Saya tidak tahu Saya belum dapat menemukannya dengan googling sederhana. Mungkin menelusuri kode sumber EF akan mengungkapkannya?
MEMark

3
FYI, kami baru saja menemukan ini dan sedang mencari untuk melakukan hal yang sama seperti OP ... menggunakannya ls variable:*sepertinya $InitialDatabasehanyalah variabel PowerShell yang didefinisikan sebagai 0, tidak ada yang lain yang didefinisikan, bahkan dalam kode sumber EF saat ini. Dan, dapatkan migrasi tidak mengembalikan apa pun, itu hanya menulis ke konsol, sehingga Anda tidak dapat beralih pada objek yang dikembalikan ...
DrewJordan

1
Ini seharusnya jawabannya
WtFudgE

76

Di EntityFrameworkCore :

Update-Database 20161012160749_AddedOrderToCourse

ke mana 20161012160749_AddedOrderToCoursenama migrasi yang ingin Anda kembalikan.


3
PERMATA! Butuh beberapa saat untuk menemukan jawaban ini (karena mereka telah mengubahnya untuk .NET Core). Pasti layak dicoba!
HockeyJ

4
Anda tidak perlu memasukkan tanggal / waktu. Anda bisa menuliskan namanya.
Richard Marskell - Drackir

1
Ini tidak berfungsi untuk saya ... ia akan mengatakan "Selesai" tetapi semua migrasi setelah yang saya tentukan tetap ada. Dan tidak ada kode "Down" di migrasi yang dijalankan.
egmfrs

Anda juga dapat menjalankan kembali ke migrasi tertentu seperti itu: Perbarui-Database-Migrasi: "AddedOrderToCourse" Terutama ketika menggunakan kosong dalam nama migrasi, ini adalah cara untuk melakukannya. (yaitu Pembaruan-Database -Migrasi "Tambah Pesanan ke Kursus")
SwissCoder

13

Solusinya adalah:

Update-Database TargetMigration 201609261919239_yourLastMigrationSucess

10
Ini sudah dikatakan dalam pertanyaan, penanya sudah tahu ini. Saya tidak melihat bagaimana ini membantu, mungkin Anda bisa membuatnya lebih jelas?
ANeves

jawaban ini lebih ringkas. TY Max!
andreikashin

4

Pengingat tambahan:

Jika Anda memiliki beberapa jenis konfigurasi, Anda perlu menentukan [ConfigurationName]

Update-Database -Configurationtypename [ConfigurationName] -TargetMigration [MigrationName]

3

Di EF Core Anda dapat memasukkan perintah Remove-Migrationdi konsol manajer paket setelah menambahkan migrasi yang salah.

Konsol menyarankan Anda melakukannya jika migrasi Anda dapat melibatkan hilangnya data:

Suatu operasi dirancah yang dapat menyebabkan hilangnya data. Harap tinjau migrasi untuk keakuratan. Untuk membatalkan tindakan ini, gunakan Hapus-Migrasi.


3
update-database 0

Peringatan : Ini akan mengembalikan SEMUA migrasi di EFCore! Silakan gunakan dengan hati-hati :)


2

Saya menemukan bahwa ini berfungsi ketika dijalankan di Package Manager Console:

dotnet ef migrations list | select -Last 2 | select -First 1 | ForEach-Object { Update-Database -Migration $_ }

Anda dapat membuat skrip yang membuatnya lebih mudah.


1

Saya menggunakan EntityFrameworkCore dan saya menggunakan jawabannya oleh @MaciejLisCK. Jika Anda memiliki beberapa konteks DB, Anda juga perlu menentukan konteks dengan menambahkan parameter konteks misalnya:

Update-Database 201207211340509_MyMigration -context myDBcontext

(di mana 201207211340509_MyMigrationmigrasi yang ingin Anda putar kembali, dan myDBcontextmerupakan nama konteks DB Anda)



0

Jika ada kemungkinan untuk dataloss, EF tidak menyelesaikan perintah pembaruan-basis data karena AutomaticMigrationDataLossAllowed = false secara default, dan roolbacks tindakan kecuali jika Anda menjalankannya dengan parameter -force .

Update-Database TargetMigration:"Your migration name" -force

atau

Update-Database TargetMigration:Your_Migration_Index -force
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.