Veritabanlarını ayırmak için birden çok bağlam için EF geçişlerini nasıl etkinleştiririm?


122

Her bağlamın kendi veritabanına karşılık geldiği aynı projede birden çok DB bağlamı için Entity Framework 5 (sürüm 5.0.0) geçişlerini nasıl etkinleştirebilirim? Ben çalıştırdığınızda Enable-Migrations(2012 Studio Görsel) PM konsolunda, çünkü birden bağlamları orada olmanın bir hata vardır:

PM> Enable-Migrations
More than one context type was found in the assembly 'DatabaseService'.
To enable migrations for DatabaseService.Models.Product1DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext.
To enable migrations for DatabaseService.Models.Product2DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext.

Çalıştırırsam, zaten bir taşıma mevcut olduğu için koşmama Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContextizin verilmiyor Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext:Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.


Yanıtlar:


126

2. Enable-Migrations çağrısı, Configuration.cs dosyası zaten mevcut olduğundan başarısız oluyor. Bu sınıfı ve dosyayı yeniden adlandırırsanız, başka bir Configuration.cs oluşturacak olan 2. Enable-Migrations'ı çalıştırabilmeniz gerekir.

Daha sonra veritabanlarını güncellerken hangi yapılandırmayı kullanmak istediğinizi belirtmeniz gerekecektir.

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
"MyRenamedConfiguration" nedir?
Robert Noack

1
"MyRenamedConfiguration", örnek olarak yalnızca yer tutucu metindir. Orijinal Configuration.cs dosyanızı herhangi bir şekilde yeniden adlandırabilirsiniz (örn. FooBar, ardından Update-Database -ConfigurationTypeName FooBar komutunu çalıştırın).
ckal

3
kısaltın: Update-Database -conf MyRenamedConfiguration
Peter Kerr

100

@Ckal'ın önerdiklerine ek olarak, bu kritik her yeniden adlandırılan Configuration.cs'ye kendi ad alanını vermek . Bunu yapmazsanız, EF, geçişleri yanlış bağlama uygulamaya çalışacaktır.

İşte benim için işe yarayan belirli adımlar.

Taşıma işlemleri karıştıysa ve yeni bir "temel" oluşturmak istiyorsanız:

  1. Taşıma klasöründeki tüm mevcut .cs dosyalarını silin
  2. SSMS'de __MigrationHistory sistem tablosunu silin.

İlk geçişin oluşturulması:

  1. Paket Yöneticisi Konsolunda:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. Çözüm Gezgini'nde: Migrations.Configuration.cs'yi Migrations.ConfigurationA.cs olarak yeniden adlandırın. Bu, Visual Studio kullanılıyorsa yapıcıyı otomatik olarak yeniden adlandırmalıdır. Olduğundan emin olun. ConfigurationA.cs Düzenle: Ad alanını NamespaceOfContext.Migrations.MigrationsA olarak değiştirin

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. Çözüm Gezgini'nde: Migrations.Configuration.cs dosyasını Migrations.ConfigurationB.cs olarak yeniden adlandırın. Yine, yapıcının da uygun şekilde yeniden adlandırıldığından emin olun. ConfigurationB.cs'yi Düzenle: Ad alanını NamespaceOfContext.Migrations.MigrationsB olarak değiştirin

  5. add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB 
  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB
  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName
    ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName
    NameOfMainProject  -ConnectionStringName ContextA 
  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

Paket Yöneticisi Konsolu'nda geçiş komut dosyaları oluşturma adımları:

  1. Komut çalıştır

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    veya -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

    Değişiklikler DB'ye uygulanana kadar bu komutu yeniden çalıştırmak sorun değil.

  2. Ya betikleri istenen yerel veri tabanına karşı çalıştırın ya da yerel olarak uygulamak için -Script olmadan Güncelle-Veritabanını çalıştırın:

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    veya -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

# 4 değişiklik: Yapılandırmayı Düzenle A.cs -> Yapılandırmayı Düzenle
B.cs

1
@Biran: Bunu fark ettiğiniz için teşekkürler. Cevabı düzenledim. Not, cevapları kendiniz de düzenleyebilirsiniz. Henüz 2000 itibarınız olmadığından, bir inceleme kuyruğuna vereceğiniz yanıtlar genellikle hızlı bir şekilde işlenir, bu nedenle düzenlemeniz muhtemelen birkaç dakika içinde onaylanmış olacaktır.
Eric J.

5
TEŞEKKÜR EDERİM! Kaçırdığım şey buydu (ad alanları).
William M. Rawls

Bu yardımcı olabilir, çünkü başlangıçta 2. ve 4. adımlarda yeniden adlandırma işleminin nasıl yapılacağı açık değildi : Configuration.cs dosyasını ConfigurationA.cs veya ConfigurationB.cs olarak yeniden adlandırdığınızda, yeniden adlandırma da sınıf ve yapıcısı da ConfigurationA veya ConfigurationB olarak yeniden adlandırılıyor. Sınıfın yeniden adlandırılamaması, add-migration komutunu çalıştırdığınızda bir hata mesajına neden olur - "Geçişler yapılandırma türü 'ConfigurationA' derlemede bulunamadı '..." " - ve evet, ifade aynı şekilde kötüydü VS2013 - LOL
Greg Barth'da

3
bu bana yardımcı oldu! tüm seçenekler ve siparişle talimatları tamamlayın. beni saat kurtardı
elcool

82

Aynı problemle karşılaştım ve aşağıdaki çözümü kullandım (tümü Paket Yöneticisi Konsolundan)

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB

Bu, Migrations klasöründe 2 ayrı klasör oluşturacaktır. Her biri oluşturulan Configuration.csdosyayı içerecektir . Maalesef bu Configuration.csdosyaları yeniden adlandırmanız gerekiyor, aksi takdirde iki tanesine sahip olmakla ilgili şikayetler olacaktır. Dosyalarımı ConfigA.csve olarak yeniden adlandırdımConfigB.cs

DÜZENLEME : (Kevin McPheat'ın izniyle) Configuration.cs dosyalarını yeniden adlandırırken hatırlayın, ayrıca sınıf adlarını ve kurucuları yeniden adlandırın / EDIT

Bu yapı ile kolayca yapabilirsiniz

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB

Yapılandırma dosyalarının yanındaki klasörün içinde taşıma için kod dosyaları oluşturacaktır (bu dosyaları bir arada tutmak güzeldir)

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB

Ve son olarak, ancak en az değil, bu iki komut, ilgili veritabanlarına doğru geçişleri uygulayacaktır.

EDIT 08 Şubat 2016: EF7 sürüm 7.0.0-rc1-16348 ile küçük bir test yaptım

Çalışmak için -o | --outputDir seçeneğini alamadım. Vermeye devam ettiMicrosoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

Bununla birlikte, bir taşıma ilk kez eklendiğinde, Geçişler klasörüne eklenmiş gibi görünüyor ve ardından başka bir bağlam için geçiş otomatik olarak bir geçiş alt doldurucusuna yerleştiriliyor.

Orijinal adlar ContextAbazı adlandırma kurallarını ihlal ediyor gibi görünüyor, bu yüzden şimdi ContextAContextve kullanıyorum ContextBContext. Bu adları kullanarak aşağıdaki komutları kullanabilirsiniz: (dnx'imin hala paket yöneticisi konsolundan çalıştığını ve geçişleri yapmak için ayrı bir CMD penceresi açmayı sevmediğimi unutmayın)

PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"

Bu, için Migrationsklasörde bir model anlık görüntüsü ve ilk geçişi oluşturacaktır ContextAContext. Bu ContextBdosyaları içeren bir klasör oluşturacaktır .ContextBContext

Manuel olarak bir ContextAklasör ekledim ve taşıma dosyalarını ContextAContextbu klasörden taşıdım . Daha sonra bu dosyaların içindeki ad alanını yeniden adlandırdım (anlık görüntü dosyası, ilk geçiş ve ilk geçiş dosyasının altında üçüncü bir dosya olduğuna dikkat edin ... designer.cs). Ad alanına eklemem .ContextAgerekiyordu ve buradan çerçeve onu otomatik olarak yeniden ele alıyor.

Aşağıdaki komutları kullanmak, her bağlam için yeni bir geçiş oluşturacaktır.

PM>  dnx ef migrations add Update1 -c "ContextAContext"
PM>  dnx ef migrations add Update1 -c "ContextBContext"

ve oluşturulan dosyalar doğru klasörlere yerleştirilir.


5
en iyi çözüm, basit ve temiz bir klasör tutuyoruz.
Malick

2
İhtiyacım olan cevap buydu. Cevap, -MigrationsDirectory aracılığıyla eklenen ad alanıydı! Teşekkür ederim.
Crob

1
Güzel ve temiz çözüm. Teşekkürler.
Stefan Cebulak

4
1,5 yıl sonra, yeni bir proje oluşturmak için kendi yazımı kullanabildiğim için mutluyum.
bart

1
Çalıştırdığınızda add-migration, sizden isteyeceğini unutmayın Name. Zaten sağladığımdan ConfigurationTypeNameve az önce söylediğimde biraz sinirlendiğim için bu beni biraz attı Name:. Ancak elbette istediği Ad, değişikliğin 'insanlar tarafından okunabilir' açıklamasıdır - örn. AddedProductsveya IncreaseLengthOfNameFields. Geçişler klasöründe bunu sınıf adının bir parçası olarak alacaksınız, böylece ne olduğunu görmek kolaydır. Yani aslında Namebir tür check-in yorumu gibidir.
Simon_Weaver

7

Zaten birçok taşıma içeren bir "Yapılandırma" ya sahipseniz ve bunu olduğu gibi tutmak istiyorsanız, her zaman yeni bir "Yapılandırma" sınıfı oluşturabilir, buna başka bir ad verebilirsiniz.

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}

o zaman sadece komutu ver

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

ve EF geçişi sorunsuz bir şekilde destekleyecektir. Sonunda veritabanınızı güncelleyin, bundan sonra, hangi yapılandırmayı güncellemek istediğinizi ona söylemezseniz EF şikayet edecek:

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

Bitti.

"Yapılandırma" nın zaten mevcut olduğundan şikayet edeceğinden ve mevcut Yapılandırma sınıfınızı yeniden adlandırmak geçiş geçmişine sorunları getireceğinden, Enable-Migrations ile uğraşmanıza gerek yoktur.

Farklı veritabanlarını veya aynı veritabanlarını hedefleyebilirsiniz, tüm yapılandırmalar __MigrationHistory tablosunu güzel bir şekilde paylaşacaktır.


4

Daha fazla veritabanı mevcutsa, PowerShell'de aşağıdaki kodları kullanın

Add-Migration Starter -context EnrollmentAppContext 
  • "Başlangıç", Geçiş Adıdır

  • 'EnrollmentAppContext', uygulama Context'in adıdır

PowerShell'i VS'de şu şekilde açabilirsiniz: Tools->NuGet Package Manager->Package Manager Console


1
Bu bana yardımcı oldu. Teşekkürler! :)
noobprogrammer

3

PowerShell'de aşağıdaki kodları takip eden veritabanı türünü güncellemek için ...

Update-Database -context EnrollmentAppContext

* birden fazla veritabanı mevcutsa, yalnızca bu kodları kullanın, aksi takdirde gerekli değildir ..


0

EF 4.7, birden çok bağlamda Enable-migrations çalıştırdığınızda aslında bir ipucu verir.

'Service.Domain' derlemesinde birden fazla bağlam türü bulundu.

To enable migrations for 'Service.Domain.DatabaseContext.Context1', 
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context1.
To enable migrations for 'Service.Domain.DatabaseContext.Context2',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context2.
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.