複数のコンテキストのEF移行を有効にしてデータベースを分離するにはどうすればよいですか?


122

同じコンテキスト内の複数のDBコンテキストに対してEntity Framework 5(バージョン5.0.0)の移行を有効にするにはどうすればよいですか(各コンテキストは独自のデータベースに対応しています)?Enable-MigrationsPMコンソール(Visual Studio 2012)で実行すると、複数のコンテキストがあるためエラーが発生します。

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.

私が実行した場合Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext、私は実行することはできませんよEnable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext移行がすでに存在するため:Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.


回答:


126

Configuration.csファイルが既に存在するため、Enable-Migrationsへの2番目の呼び出しは失敗します。そのクラスとファイルの名前を変更すると、その2番目のEnable-Migrationsを実行できるようになり、別のConfiguration.csが作成されます。

次に、データベースの更新時に使用する構成を指定する必要があります。

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
「MyRenamedConfiguration」とは何ですか?
Robert Noack

1
「MyRenamedConfiguration」は、単なる例としてのプレースホルダーテキストです。元のConfiguration.csの名前を任意に変更できます(例:FooBar、次にUpdate-Database -ConfigurationTypeName FooBarを実行)。
ckal 2014年

3
短縮形:Update-Database -conf MyRenamedConfiguration
Peter Kerr

100

@ckalの提案に加えて、名前を変更した各Configuration.csに独自の名前空間を与えることが重要です。そうしないと、EFは誤ったコンテキストに移行を適用しようとします。

以下は、私にとって効果的な特定の手順です。

移行が失敗し、新しい「ベースライン」を作成したい場合:

  1. Migrationsフォルダー内の既存の.csファイルを削除する
  2. SSMSで、__ MigrationHistoryシステムテーブルを削除します。

初期移行の作成:

  1. パッケージマネージャーコンソール:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. ソリューションエクスプローラーで:Migrations.Configuration.csの名前をMigrations.ConfigurationA.csに変更します。Visual Studioを使用している場合は、コンストラクターの名前が自動的に変更されます。確認してください。ConfigurationA.csの編集:名前空間をNamespaceOfContext.Migrations.MigrationsAに変更します。

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. ソリューションエクスプローラーで:Migrations.Configuration.csの名前をMigrations.ConfigurationB.csに変更します。繰り返しになりますが、コンストラクタの名前も適切に変更されていることを確認してください。ConfigurationB.csの編集:名前空間をNamespaceOfContext.Migrations.MigrationsBに変更します。

  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

パッケージマネージャーコンソールで移行スクリプトを作成する手順:

  1. コマンドを実行

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

    または-

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

    変更がDBに適用されるまで、このコマンドを再実行しても問題ありません。

  2. 目的のローカルデータベースに対してスクリプトを実行するか、-ScriptなしでUpdate-Databaseを実行してローカルに適用します。

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

    または-

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

#4の変更:ConfigurationA.csの編集-> ConfigurationB.csの編集
ブライアンリゾ

1
@Biran:気づいてくれてありがとう。答えを編集しました。自分で回答を編集することもできます。まだ2000年の評判がないため、回答はレビューキューに入れられますが、そのキューは通常、迅速に処理されるため、編集は数分以内に承認される可能性があります。
エリックJ.

5
ありがとうございました!それが私が欠けていたものでした(名前空間)。
ウィリアムM.ロールズ2014

最初に手順2と4で名前を変更する方法がはっきりしなかったため、これが役立つ場合があります。Configuration.csファイルの名前をConfigurationA.csまたはConfigurationB.csに変更すると、名前の変更によってクラスとそのコンストラクターもConfigurationAまたはConfigurationBに名前変更されます。クラスの名前を変更しないと、add-migrationコマンドを実行すると、エラーメッセージが表示されます- 「移行構成タイプ 'ConfigurationA'がアセンブリ '...'に見つかりませんでした」 -はい、文言は間違っていますそれはVS2013で取得したエラーメッセージにあります-LOL
Greg Barth

3
これは私を助けました!すべてのオプションと注文を含む完全な指示。時間を節約しました
elcool 2015

81

私は同じ問題にぶつかっただけで、次の解決策を使用しました(すべてPackage Manager Consoleから)

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

これにより、Migrationsフォルダーに2つの別個のフォルダーが作成されます。それぞれに生成されたConfiguration.csファイルが含まれます。残念ながら、これらのConfiguration.csファイルの名前を変更する必要があります。そうしないと、ファイルが2つあることに不満があります。ファイルの名前をConfigA.csおよびに変更しましたConfigB.cs

編集:(提供:Kevin McPheat)Configuration.csファイルの名前を変更するときは、クラス名とコンストラクターの名前も変更してください/ EDIT

この構造で、あなたは簡単に行うことができます

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

構成ファイルの横のフォルダー内に移行用のコードファイルを作成します(これらのファイルをまとめておくと便利です)。

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

そして最後に、これらの2つのコマンドは、対応するデータベースに正しい移行を適用します。

EDIT 08 Feb、2016: EF7バージョン7.0.0-rc1-16348で少しテストを行いました

-o | --outputDirオプションを機能させることができませんでした。それは与え続けたMicrosoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

ただし、マイグレーションが初めて追加されたときは、Migrationsフォルダーに追加され、その後の別のコンテキストのマイグレーションは自動的にマイグレーションのサブドルダーに入れられます。

元の名前ContextAはいくつかの命名規則に違反しているようですので、とを使用ContextAContextContextBContextます。これらの名前を使用すると、次のコマンドを使用できます(私のdnxは引き続きパッケージマネージャーコンソールから機能し、移行を行うために別のCMDウィンドウを開くのは好きではないことに注意してください)。

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

これにより、のMigrationsフォルダーにモデルのスナップショットと初期移行が作成されますContextAContext。それはContextBこれらのファイルを含むという名前のフォルダを作成しますContextBContext

手動でContextAフォルダを追加し、移行ファイルContextAContextをそのフォルダに移動しました。次に、これらのファイル内の名前空間の名前を変更しました(スナップショットファイル、最初の移行、および最初の移行ファイルの下に3番目のファイルがあることに注意してください... Designer.cs)。.ContextA名前空間に追加する必要があり、そこからフレームワークが再び自動的に処理します。

次のコマンドを使用すると、コンテキストごとに新しい移行が作成されます

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

生成されたファイルは正しいフォルダに配置されます。


5
最善の解決策であり、シンプルで、明確なフォルダを維持します。
Malick

2
これが私が必要とした答えでした。-MigrationsDirectoryによって追加された名前空間が答えでした!ありがとうございました。
Crob

1
素敵でクリーンなソリューション。ありがとう。
Stefan Cebulak 2016年

4
1.5年後、自分の投稿を使用して新しいプロジェクトをセットアップできてうれしいです。
Bart s

1
実行add-migrationすると、プロンプトが表示されることに注意してくださいName。私はすでに提供ConfigurationTypeNameしていたので、これは私をわずかに失望させ、そしてちょうどそれが言ったときにわずかにイライラしましたName:。しかし、もちろん、必要な名前は、変更についての「人間が読める」説明です。AddedProductsまたはIncreaseLengthOfNameFields。Migrationsフォルダーでは、これをクラス名の一部として取得するので、何が何であるかを簡単に確認できます。つまり、実質的にNameはチェックインコメントのようなものです。
Simon_Weaver 2017

7

多くの移行を伴う「構成」がすでにあり、これをそのまま保持したい場合は、常に新しい「構成」クラスを作成し、次のように別の名前を付けることができます

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

次に、コマンドを発行します

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

EFは問題なく移行を足場します。最後にデータベースを更新します。これから、どの構成を更新するかをEFに指示しないと、EFは文句を言います。

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

できました。

Enable-Migrationsは「Configuration」がすでに存在するというメッセージを表示するため、対処する必要はありません。既存のConfigurationクラスの名前を変更すると、移行履歴に問題が発生します。

別のデータベースをターゲットにすることも、同じデータベースをターゲットにすることもできます。すべての構成が__MigrationHistoryテーブルを適切に共有します。


4

さらにデータベースが存在する場合は、PowerShellで次のコードを使用します

Add-Migration Starter -context EnrollmentAppContext 
  • 「スターター」は移行名です

  • 'EnrollmentAppContext'は私のアプリコンテキストの名前です

VSでPowerShellを開くには、次のようにします。 Tools->NuGet Package Manager->Package Manager Console


1
これは私を助けました。ありがとう!:)
noobprogrammer

3

PowerShellでコードに従ってデータベースタイプを更新するには...

Update-Database -context EnrollmentAppContext

*複数のデータベースが存在する場合、このコードのみを使用します。それ以外の場合は必要ありません。


0

複数のコンテキストで移行の有効化を実行すると、EF 4.7は実際にヒントを与えます。

アセンブリ 'Service.Domain'で複数のコンテキストタイプが見つかりました。

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.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.