3

コードファースト移行が有効になっているEntityFramework5を実行しています。データベース初期化子を使用して実行する:MigrateToLatestVersion

最新の安定したブランチで実行されているいくつかの顧客が住んでいます。トランク/マスターで新しいコードを開発している間、分岐コードfxで実行されている顧客データベースに接続する必要がある場合があります。ある種のデータバグをデバッグします。

誰かが顧客が実行しているブランチに切り替えるのを忘れた場合、これは「危険」になる可能性があります。移行により、その人が実行しているコードに合わせて顧客データベースがアップグレードされるためです。

1つの解決策は、最新バージョンに移行しない別の初期化子を実行することです。しかし、それは、新しいシステムを新しい顧客に展開したり、新しい誰かがチームに加わって、立ち上がって実行する必要がある場合に、より多くの作業を意味します。

この問題を解決するために、app.configにboolを設定して、コードを「最新バージョンに移行」するかどうかを設定し、開発では常にfalseにして、顧客にデプロイするときに変換することを考えていました。

そうすれば、データベースを最新バージョンに自動的に更新できるというメリットがありますが、開発者が誤って古いバージョンのコードのシステムに接続したり、移行によってそのデータベースが破壊されたりする危険はありません。

これで、基本的にこれを確認する必要があります。

(簡略化されたコード)

if(Config.MigrateToLatestVersion || !databaseExists) 
{
  var initializer = new MigrateToLatestVersion<MyContext,MigrationConfiguration>();
  Database.SetInitializer(initializer);
  using(var context = new MyContext())
  {
    context.Database.Initialize(true)
  }
}

私の質問は、移行を実行せずにデータベースが存在するかどうかを確認する方法についてでしたが、これを実行できることがわかりました。

Database.SetInitializer<MyContext>(null);
var context = new MyContext();
var databaseExists = context.Database.Exists();

ただしMigrateToLatestVersion、データベースが存在しない場合、またはパッケージマネージャーコンソールから手動でUpdate-Databaseを実行する場合にのみ、初期化子を実行する場合。

最初に2つの問題があります。モデルがデータベースと異なるかどうかという例外が発生しなくなりました。2番目:MigrationConfigurationにあるシードメソッドを実行しません。これはまだ実行したい場合があります。

Migrations Initializerを実行してすべての利点を得る方法についての提案はありますが、誰かが誤って本番環境を壊す可能性を防ぐ何かがありますか?

4

1 に答える 1

4

だから私が行った解決策は、という新しいDatabaseInitializerを作ることでしたMigrateDatabaseToLatestIfLocal

MigrateDatabaseToLatestVersionイニシャライザーがどのように機能するかを見て、データベースが存在するかどうかと、ローカルまたはリモートで実行されているかどうかを確認する点が異なります(これを決定するための構成変換の助けを借りて。リモートシステムでは、データソースが変換されています構成ファイル。)

public class MigrateDatabaseToLatestIfLocal<TContext, TMigrationsConfiguration> : IDatabaseInitializer<TContext>
        where TContext : DbContext
        where TMigrationsConfiguration : DbMigrationsConfiguration<TContext>, new()
    {
        private DbMigrationsConfiguration _config;

        public MigrateDatabaseToLatestIfLocal()
        {
            this._config = (DbMigrationsConfiguration)Activator.CreateInstance<TMigrationsConfiguration>();
        }

        public MigrateDatabaseToLatestIfLocal(string connectionStringName)
        {
          MigrateDatabaseToLatestIfLocal<TContext, TMigrationsConfiguration> databaseToLatestVersion = this;
          var instance = Activator.CreateInstance<TMigrationsConfiguration>();
          instance.TargetDatabase = new DbConnectionInfo(connectionStringName);
            databaseToLatestVersion._config = instance;
        }

        public void InitializeDatabase(TContext context)
        {
            var databaseExists = context.Database.Exists();

            var migrator = new DbMigrator(this._config);
            var pendingMigrations = migrator.GetPendingMigrations().OrderByDescending(s => s);
            var localMigrations = migrator.GetLocalMigrations().OrderByDescending(s => s);
            var dbMigrations = migrator.GetDatabaseMigrations().OrderByDescending(s => s);


            var isRemoteConnection = FunctionToFindOutIfWeAreRemote(); //here we check the config file to see if the datasource is a certain IP, this differentiates locally and remotely because of config tranformation.

            if (isRemoteConnection && databaseExists)
            {
                if (pendingMigrations.Any())
                {
                    throw new MigrationsException("You are not allowed to automatically update the database remotely.")
                }
                if (localMigrations.First() != dbMigrations.First())
                {
                    throw new MigrationsException("Migrations in code and database dont match, please make sure you are running the code supported by the remote system. ");
                }
            }
            else
            {
                //we are local, fine update the db and run seeding.
                //we are remote and the db does not exist, fine update and run seed.
                migrator.Update();
            }
        }
    }

これは非常に特殊なケースかもしれませんが、私にとっては、コードの最初の移行を実行するときにある程度の安全性を提供し、ライブ環境を誤ってランダムに移行しないようにします

于 2013-01-30T12:42:50.073 に答える