Entity Framework geri alma ve hatalı taşımayı kaldırma


175

EF 6.0'ı manuel taşıma ve güncellemelerle C # projem için kullanıyorum. Veritabanında yaklaşık 5 taşıma var, ancak son taşıma işleminin kötü olduğunu ve istemediğimi fark ettim. Önceki bir geçişe geri dönebileceğimi biliyorum, ancak yeni (sabit) bir geçiş eklediğimde ve Update-Database'i çalıştırdığımda, kötü geçiş bile uygulanıyor.

Önceki geçişe geri dönmeye ve dosyayı kötü geçişle silmeye çalışıyordum. Ancak, yeni taşıma eklemeye çalıştığımda, taşıma dosyası bozuk olduğu için veritabanını güncellerken hata alıyorum (daha spesifik olarak, ilk kod satırı A tablosunu B olarak yeniden adlandırıyor ve sonraki satırlar, EF tabloyu güncellemeye çalışıyor adı A - belki bazı EF hatasıdır).

Çalıştırabileceğim bazı sorgu var mı, EF'e "Hiç olmadığı gibi son göçü unut, kötüydü" gibi bir şey söyler mi? Kaldır-Göç gibi bir şey.

Edit1 Benim için uygun bir çözüm buldum. Modeli iyi duruma getirmek ve çalıştırmak Add-Migration TheBadMigration -Force. Bu, son uygulanmayan geçişi yeniden yapılandıracaktır.

Her neyse, bu hala orijinal soruya tam olarak cevap vermiyor. Veritabanını kötü geçişe güncellersem, geri alma ve yeni geçişi nasıl oluşturabileceğimi, kötü olanı hariç tutmanın iyi bir yolunu bulamadım.

Teşekkürler


Visual studio'yu yeniden başlatmak zorunda kaldım ve daha sonra düzgün çalışmaya başladı. Bu, bana zaten birkaç kez oldu, her zaman veritabanını güncellemeden göçlerle uğraştıktan sonra, buradaki takımlarda garip bir şey oluyor.
Andrei Dvoynos

Yanıtlar:


167

2 seçeneğiniz var:

  • Down'u kötü taşıma işleminden alıp yeni bir taşıma işlemine dahil edebilirsiniz (modelde sonraki değişiklikleri de yapmanız gerekir). Bu, daha iyi bir sürüme etkin bir şekilde yuvarlanıyor.

    Bu seçeneği birden çok ortama giden şeylerde kullanıyorum.

  • Diğer seçenek, Update-Database –TargetMigration: TheLastGoodMigrationkonuşlandırılan veritabanınıza karşı çalışacak ve daha sonra geçişi çözümünüzden silmektir. Bu tür hulk şut alternatifidir ve bunun kötü sürümle dağıtılan herhangi bir veritabanına karşı gerçekleştirilmesini gerektirir.

    Not: Kullanabileceğiniz taşıma işlemini yeniden oluşturmak için Add-Migration [existingname] -Force. Ancak bu, mevcut taşıma işleminizin üzerine yazacaktır. Bu nedenle, yalnızca mevcut taşıma işlemini veritabanından kaldırdıysanız emin olun. Bu, mevcut taşıma dosyasını silmek ve çalıştırmakla aynı şeyi yaparadd-migration

    Bu seçeneği geliştirirken kullanıyorum.


1
Hulk Smash seçeneği çalışmıyor. Veritabanına kötü geçişi henüz uygulamadım. Denedim, ama işe yaramadı, çünkü orijinal soruda belirttiğim tablo adları. İlk seçeneği çok sevmiyorum, çünkü göç kodunu değiştirmek zorunda kalacak gibi görünüyor. Eğer kötü yaparsam, hepsini bozabilirim.
Martin Brabec

8
Kötü göçü henüz uygulamadıysanız, onu silmenizi ve yeniden taşımayı veya kırık göçü düzeltmenizi engelleyen hiçbir şey yoktur.
Sevilmedi

4
'Hulk şutu' cevabı, gelişirken benim için çalışıyor ve kaçırdığım göçe bir şeyler eklemek istiyorum. Ben Martin için işe yaramadı nedenleri ilgisiz (ya da muhtemelen veritabanı şemasını manuel olarak değiştirme ile ilgili) düşünüyorum
rethenhouser2

1
@BenRethmeier genel bir kural olarak hulk şut seçeneğini sadece gelişirken kullanıyorum. Üretimde, sorunu gidermek için her zaman yeni bir geçiş oluştururum. Bunun nedeni, veritabanını indiriyorsanız manuel müdahaleye ihtiyaç duymanızdır. Ürüne manuel müdahale gerektiren hiçbir şeyi sevmiyorum.
sevilen Değil

1
HULK SMASH !!!! --- Güzel olmayı denedim ama EF oynamadı - Bilinen son sürüme geri döndüm - (Taşıma dosyalarını yedekledim) Silindi, Geçiş Eklendi - Zorla - Öncekine yeniden adlandırıldı ve kodu kopyaladı. ikinci göç aynı şekilde - hata yok - normale dön
Traci

127

Sorunun da belirttiği gibi, bu henüz yayınlanmamış bir geliştirme türü ortamındaki bir göç için geçerlidir.

Bu sorun şu adımlarda çözülebilir: veritabanınızı son iyi geçişe geri yükleyin, kötü geçişi Entity Framework projenizden silin, yeni bir taşıma oluşturun ve veritabanına uygulayın. Not: Yorumlardan yola çıkarak EF Core kullanıyorsanız bu komutlar artık geçerli olmayabilir.

1. Adım: Önceki bir taşıma işlemine geri yükleme

Taşıma işleminizi henüz uygulamadıysanız bu bölümü atlayabilirsiniz. Veritabanı şemanızı önceki bir noktaya geri yüklemek için -TargetMigration seçeneğiyle birlikte Veritabanı Güncelleştir komutu son iyi geçişi belirtin. Varlık çerçeve kodunuz çözümünüzdeki farklı bir projede bulunuyorsa, '-Project' seçeneğini kullanmanız veya paket yöneticisi konsolunda varsayılan projeyi değiştirmeniz gerekebilir.

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

Son iyi geçişin adını almak için veritabanınıza uygulanan geçiş adlarının bir listesini almak üzere 'Get-Migrations' komutunu kullanın.

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

Bu liste önce en son uygulanan taşıma işlemlerini gösterir. Alt sürüme geçirmek istediğiniz işlemden sonra, yani alt sürüme geçirmek istediğiniz işlemden önce uygulanan geçişi seçin. Şimdi bir Güncelleme Veritabanı oluşturun.

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

Belirtilenden sonra uygulanan tüm geçişler, en son uygulanan ilk taşıma işleminden başlayarak sırayla derecelendirilir.

2. Adım: Taşıma işleminizi projeden silin

remove-migration name_of_bad_migration

Eğer remove-migration komut İdare Framework sürümü mevcut değildir, istenmeyen göç EF projesi manuel 'göçler' klasörünün dosyaları silin. Bu noktada, yeni bir taşıma oluşturabilir ve veritabanına uygulayabilirsiniz.

3. Adım: Yeni taşıma işleminizi ekleyin

add-migration my_new_migration

4. Adım: Taşıma işleminizi veritabanına uygulayın

update-database

6
EF Core ile Get-Migrations kaldırılmış görünüyor.
Kevin Burton

1
Adım 2 ! - Çok kullanışlı bir özellik. @KevinBurton'un belirttiği gibi. Ve sonra add-migration "new migration",update-database
Alexander Frolov

2
Güncelleme-Veritabanı – göç: "<daha önce uygulanan geçiş>" @David Sopko
Fuat

Teşekkürler @AlexanderFrolov Yorumlarınızı yansıtacak şekilde çözümü güncelledim.
David Sopko

1
adım 2'den sonra kaldır-kaldır kullanmamız gerekiyor
Rahul

56

ASP.NET Core v1.0.0 ile EF Core kullananlara benzer bir sorun yaşadım ve düzeltmek için aşağıdaki komutları kullandım (@ DavidSopko'nun gönderisi beni doğru yönde gösterdi, ancak ayrıntılar EF Core için biraz farklıdır) :

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

Örneğin, şu anki gelişimimde komut

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

Remove-Migration, uyguladığınız son geçişi kaldıracak. Kaldırmak için birden fazla geçiş içeren daha karmaşık bir senaryo varsa (sadece 2, ilk ve kötü olanı vardı), bir kukla projedeki adımları test etmenizi öneririm.

Şu anda EF Core'da (v1.0.0) bir Get-Migrations komutu yok gibi görünüyor, bu nedenle migrations klasörünüze bakmalı ve yaptıklarınızı bilmelisiniz. Ancak, güzel bir yardım komutu var:

PM> get-help entityframework

VS2015 SQL Server Nesne Gezgini'nde veritabanını yenileyerek, tüm verilerim korundu ve geri dönmek istediğim geçiş gitti :)

Başlangıçta Remove-Migration'ı kendi başına denedim ve hata komutunun kafa karıştırıcı olduğunu gördüm:

System.InvalidOperationException: '...' geçişi zaten veritabanına uygulandı. Uygulamayı kaldırın ve tekrar deneyin. Taşıma başka veritabanlarına uygulandıysa, yeni bir taşıma kullanarak değişikliklerini geri almayı düşünün.

Bu ifadeyi geliştirmeye yönelik öneriler var, ancak hatanın böyle bir şey söylemek istiyorum:

Veritabanı şemasını bu duruma geri döndürmek için Update-Database'i (son iyi taşıma adı) çalıştırın. Bu komut, Güncelleştirme-Veritabanı'na belirtilen geçişten sonra gerçekleşen tüm taşıma işlemlerinin uygulamasını kaldırır. Daha sonra Remove-Migration'ı (kaldıracağınız taşıma adı) çalıştırabilirsiniz.

EF Çekirdek yardım komutundan çıktı şu şekildedir:

 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

Ayrıca kullanabilirsiniz

Remove-Migration -Force

Bu, son uygulanan taşıma işlemini geri alır ve kaldırır


4

İlk olarak, son mükemmel geçişinizi bu komutla güncelleyin:

Update-Database TargetMigration

Misal:

Update-Database -20180906131107_xxxx_xxxx

Ardından, kullanılmayan taşıma işleminizi manuel olarak silin.


2
olması gereken: Update-Database -TargetMigration 20180906131107_xxxx_xxxx
Elger Mensonides

Update-Database 20180906131107_xxxx_xxxx(tire yok) benim için çalıştı. TargetMigrationAnahtar olarak hiçbir sürümü çalıştı. Bu komutlar hareketli bir hedef gibi görünüyor (yani her sürümde bunları değiştiriyor)?
Toplam Yok

3

.NET Core 2.2'den TargetMigrationitibaren gitmiş gibi görünüyor:

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"

Şimdi bu benim için çalışıyor:

Update-Database -Migration 20180906131107_xxxx_xxxx

Yanı sıra ( -Migrationanahtar yok ):

Update-Database 20180906131107_xxxx_xxxx

Eklenen bir notta, Model Anlık Görüntünüzü senkronize etmeden artık taşıma klasörlerini temiz bir şekilde silemezsiniz. Bu yüzden bunu zor yoldan öğrenir ve değişikliklerin olması gerektiğini bildiğiniz boş bir geçişle tamamlanırsanız, koşabilirsiniz (son geçiş için anahtar gerekmez):

Remove-migration

Son taşıma klasörü el ile silinmiş olsa bile, karışıklığı temizler ve olması gereken yere geri koyar.


0

EF 6 için, geliştirme aşamasında çok fazla iskele kullanıyorsanız, tek katmanlı. Sadece varsları güncelleyin ve durulamak ve tekrarlamak için paket yöneticisi konsolundaki yukarı oku kullanmaya devam edin.

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

Bu neden gerekli? Bunun hangi EF6 sürümlerinin geçerli olduğundan emin değilsiniz, ancak yeni geçiş hedefiniz zaten uygulanmışsa, Add-Migration'ta yeniden iskele için '-Force' kullanılması aslında yeniden iskele olmaz, bunun yerine yeni bir dosya oluşturur (bu iyi bir şeydir) bir şey olsa da 'Down'ınızı kaybetmek istemezsiniz). Yukarıdaki kod parçası gerekirse önce 'Aşağı' yapar, ardından -Force yeniden iskele için düzgün çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.