web-dev-qa-db-ja.com

Entity Framework、自動適用移行

AutomaticMigrationsEnabled = trueでEntity Framework Code Firstアプローチを使用しています:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////

public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
    public MigrateDBConfiguration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }
}

プロジェクトの最初の実行では、期待どおりにデータベースとテーブルが作成されます。フィールドを追加または削除してモデルを変更した後、Add-Migrationを実行しました。移行クラスは生成されましたが、プロジェクトの実行後にこの例外が発生します。

EntityFramework.dllでタイプ 'System.InvalidOperationException'の例外が発生しましたが、ユーザーコードでは処理されませんでした

追加情報:データベースが作成されてから、「DBContext」コンテキストをサポートするモデルが変更されました。

EDIT:arturo menchaca の答えのガイダンスに従って、コードを次のように変更しました。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());

...

変更後、この例外が発生します。

データベースに「MyTable」という名前のオブジェクトが既に存在します。

データベース移行を適用するにはどうすればよいですか?

13
Fred

最後に、私の問題の解決策を見つけました。各アプリケーションの開始時にこのメソッドを呼び出します:

public void InitializeDatabase(DataAccessManager context)
{
    if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
    {
        var configuration = new DbMigrationsConfiguration();
        var migrator = new DbMigrator(configuration);
        migrator.Configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");
        var migrations = migrator.GetPendingMigrations();
        if (migrations.Any())
        {
            var scriptor = new MigratorScriptingDecorator(migrator);
            var script = scriptor.ScriptUpdate(null, migrations.Last());

            if (!string.IsNullOrEmpty(script))
            {
                context.Database.ExecuteSqlCommand(script);
            }
        }
    }
}
15
Fred

自動移行は、モデルの変更に_add-migration_コマンドを実行する必要はないが、手動で_update-database_コマンドを実行する必要があることを意味します。

_update-database_を呼び出すときに自動移行が有効になっている場合、モデルに保留中の変更があると、「自動」移行が追加され、データベースが更新されます。

_update-database_コマンドを呼び出さずにデータベースを更新する場合は、次のように、コンテキストのDatabase.SetInitializer(...)メソッドにOnModelCreating()メソッドを追加できます。

_public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MigrateDBConfiguration>());
    }

    ...
}

public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<MyContext>
{
    ...
_

デフォルトのDbMigrationsConfigurationではなく、実際のコンテキストでMigrateDatabaseToLatestVersionDbContextを宣言する必要があることに注意してください。

15
Arturo Menchaca

エンティティに変更がある場合は、最初にadd-migration移行スクリプトを作成します。

その後、Global.asax

このようなコードが必要です

        var configuration = new MyProject.Configuration();
        var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);            

        migrator.Update();

asp.netプロジェクトを実行するたびに、実行して実行する新しい移行があるかどうかを確認しますupdate-database自動的に。

3
gorums