实体框架6.1.3从代码优先模型

时间:2017-03-07 09:27:22

标签: c# entity-framework entity-framework-6 code-first ef-migrations

在为生产系统发布应用程序时,我遇到了一些问题。

情况:

  • 实体框架6.1.3具有多次迁移的代码优先模型
  • 具有专用serviceuser(非本地系统)的Windows服务
  • 配置(由WPF-App处理)允许粘贴指向所需MS-SQL DB的连接字符串
  • 应该通过安装admin来准备数据库,以便serviceuser具有dbowner,dbwriter和dbreader权限。 (应该足够用于将来的迁移)
  • serviceuser不应具有SQL-Servers masterdb的权限。这就是为什么必须在启动服务之前由管理员创建所需的Windows服务数据库

我正在尝试做什么:

  • 编写IDatabaseInitializer< MyDbContext>,在检测到时初始化现有但空的数据库,并在过期模型的情况下更新数据库

我尝试了什么:

  • 使用MigrateDatabaseToLatestVersion初始值设定项=>这个失败,因为准备好但空的数据库中没有__MigrationHistory表

  • 使用CreateDatabaseIfNotExists初始值设定项=>这个失败了,因为数据库已经存在,它利用这个初始化程序来做......没什么

  • 使用以下InitializeDatabase方法编写自己的IDbInitializer:

    public void InitializeDatabase(RapasiDbContext context)
    {
        if (!context.Database.Exists()) //Shouldn't happen
        {                
          ... // Throw Execption: No prepared DB found
        }           
        try //Initialize the existing database, but only if not already done (force:false)
        {
            context.Database.InitializeDatabase(false);
        }
        catch (Exception ex)
        {
            Log.Fatal("Error while initializing the database", ex);
        }           
        try //Update the databse, if model is outdated
        {
            var dbMigrationConfig = new Configuration();
            if (dbMigrationConfig.AutomaticMigrationsEnabled && !context.Database.CompatibleWithModel(true))
            {
                Log.Info("database schame outdated, starting migration!");
                try
                {
                    var migrator = new DbMigrator(dbMigrationConfig);
                    migrator.Update();
                }
                catch (Exception ex)
                {
                    Log.Fatal("Error while migrating the database", ex);
                }
            }
        }
        catch (Exception ex)
        {
            Log.Fatal("No Migration-Histroy found!", ex);
        }
    }
    

问题

  • 在我现在尝试的方式中,初始化程序根本没有调用
  • 切换到InitializeDatabase(force:true)利用recursivly调用我自己的InitializeDatabase方法:(

问题:

如何使用我的迁移中的InitialCommit-Up()脚本初始化现有数据库?

或者我错过了一些非常明显的观点,为什么这种数据库初始化不会发生?对于我刚才不知道的情况,有没有最好的做法?

1 个答案:

答案 0 :(得分:1)

即使没有MigrateDatabaseToLatestVersion表,

__MigrationHistory初始值设定项也可以正常工作。它应该在第一次运行迁移时创建。

正如您在原始问题的评论中所说,在调用MigrateDatabaseToLatestVersion方法时,您需要为SetInitializer的构造函数参数提供正确的值:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<RapasiDbContext, Configuration>(true, new Configuration()));

the reference page所述,构造函数中的boolean参数指定是否使用触发初始化的上下文中的连接信息来执行迁移。如果缺少此参数,将从使用默认构造函数或已注册工厂构造的上下文中获取连接信息(这可能不是您所需的)。

另外,我认为您可能无法正确解释AutomaticMigrations配置。这并不意味着您的迁移将自动应用,这意味着如果您在模型更改后没有手动运行添加迁移,它们将自动生成。我想您希望在数据库不是最新时执行挂起的迁移,即使禁用了AutomaticMigrations。