我最近更改了一个应用程序,不再使用以下开发内容:
DropCreateDatabaseIfModelChanges<Context>
要使用:
public class MyDbMigrationsConfiguration: DbMigrationsConfiguration<GrsEntities>
{
public MyDbMigrationsConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
在我的数据库上下文中,我有:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Tell Code First to ignore PluralizingTableName convention
// If you keep this convention then the generated tables will have pluralized names.
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//set the initializer to migration
Database.SetInitializer(new MigrateDatabaseToLatestVersion<GrsEntities, MigrationConfig>());
}
我使用 AddOrUpdate 扩展覆盖了 DbMigrationsConfiguration 中的 Seed(context),之前我只是使用 Add 在 drop db (DropCreateDatabaseIfModelChanges) 上进行播种。
我的困惑是,无论 DbContext 是否发生任何更改,迁移都会在应用程序每次启动时运行。每次我启动应用程序(库通过服务运行)时,初始化程序都会像种子一样运行。我的预期行为是检查是否需要迁移(在幕后检查模型是否与物理数据库匹配),然后更新任何新的/删除的表/列,并且仅在发生更改时运行种子。
在我的测试中,每次都会运行种子,这是可行的,但似乎效率低下,并且不是我所期望的。不幸的是,MSDN 文档非常有限。
我是否完全误用了 MigrateDatabaseToLatestVersion?有没有办法获得我期望的行为(即,如果模型发生更改,则仅作为种子),或者我应该更改我的种子方法以期望在每次应用程序启动时运行?
最佳答案
Seed 方法仅在数据库更改时运行这一事实对于 EF 4.1 中附带的数据库初始值设定项来说是相当有限的。它是有限制的,因为有时您需要在不更改数据库的情况下更新种子数据,但要实现这一点,您必须人为地使其看起来像是数据库已更改。
通过迁移,种子的使用变得有点不同,因为不能再假设数据库开始为空——毕竟这就是迁移的目的。因此,迁移中的种子方法必须假设数据库存在并且其中可能已经有数据,但可能需要更新该数据以考虑迁移对数据库所做的更改。因此使用 AddOrUpdate。
因此,现在我们面临的情况是,必须编写 Seed 来考虑现有数据,这意味着实际上没有必要延续 EF 4.1 Seed 方法的限制,这样您就必须使其看起来像数据库已更改只是为了让种子运行。因此,现在每次在应用程序域中首次使用上下文时,Seed 都会运行。这不应该改变种子的实现方式,因为它需要处理数据已经存在的情况。
如果由于您有大量种子数据而导致性能问题,那么通常很容易在种子方法中添加检查来查询数据库以确定在执行操作之前需要完成多少工作。
关于entity-framework - 对 EF 自动迁移和播种的困惑 - 在每个程序启动时播种,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10822618/