【发布时间】:2017-03-07 09:27:21
【问题描述】:
我在为生产系统上的发布准备应用程序时遇到了一些问题。
情况:
- Entity Framework 6.1.3 Code-First Model 与多个迁移
- 具有专用服务用户(非本地系统)的 Windows 服务
- 配置(由 WPF 应用程序处理)允许粘贴指向所需 MS-SQL DB 的连接字符串
- DB 应该由安装管理员准备,以便 serviceuser 拥有 dbowner、dbwriter 和 dbreader 权限。 (对于未来的迁移应该足够了)
- serviceuser 不应拥有 SQL-Servers masterdb 的权限。这就是为什么在启动服务之前必须由管理员创建 Windows 服务所需的数据库的原因
我想要做什么:
- 编写 IDatabaseInitializer
,它会在检测到时初始化现有但为空的数据库,并在模型过时时更新数据库
我尝试了什么:
使用 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) 会导致递归调用我自己的 InitializeDatabase 方法:(
问题:
如何使用我的迁移中的 InitialCommit-Up() 脚本初始化现有数据库?
或者我错过了一些非常明显的观点,为什么这种数据库初始化不应该发生?对于我不知道的情况,是否有任何最佳做法?
【问题讨论】:
-
MigrateDatabaseToLatestVersion初始化程序应该可以工作,即使没有__MigrationHistory表。它应该在第一次运行迁移时创建。问题应该出在其他任何地方。你有什么例外吗? -
另外,我认为您可能错误地解释了
AutomaticMigrations配置。这并不意味着您的迁移将自动应用,这意味着如果您在模型更改后没有手动运行Add-Migration,它们将自动生成。我猜您希望在数据库不是最新的情况下执行待处理的迁移,即使AutomaticMigrations已禁用。 -
感谢您的建议,我在做一些更深入的测试后发现,
MigrateDatabaseToLatestVersion初始化程序有效,如果使用如下两个参数调用:Database.SetInitializer(new MigrateDatabaseToLatestVersion<RapasiDbContext, Configuration>(true, new Configuration()));。如果您编辑评论并将其发布在下面,将接受它作为答案:) -
感谢您解释基于
AutomaticMigrations-Property 应用和生成迁移的区别!
标签: c# entity-framework entity-framework-6 code-first entity-framework-migrations