Entity framework 在Entity Framework 4.3中以增量方式为数据种子的最佳方法
我一直在现有数据库上使用EntityFramework4.3,我有几个场景要考虑 首先,如果我删除了我的数据库,我想从头开始重新创建if-我已经成功地为此使用了CreateDatabaseIfNotExists数据库初始化器 其次,如果我更新了我的模型,并且数据库已经存在,我希望数据库能够自动更新——我已经成功地使用了EntityFramework4.3迁移 这是我的问题。假设我向模型中添加了一个新表,该表需要一些参考数据,这是确保在数据库初始化器运行和迁移运行时创建这些数据的最佳方法。我的愿望是,当我从头开始创建db时,以及当数据库由于迁移运行而更新时,都会创建数据 在一些EF迁移示例中,我看到人们在迁移的UP方法中使用SQL()函数来创建种子数据,但如果可能,我更愿意使用上下文来创建种子数据(如大多数数据库初始化器示例中所示)我觉得奇怪的是,当EF的整个概念都在抽象sql时,您会使用纯sql。我曾尝试在UP方法中使用上下文,但由于某种原因,当我尝试在创建表的调用的正下方添加种子数据时,它认为在迁移中创建的表不存在Entity framework 在Entity Framework 4.3中以增量方式为数据种子的最佳方法,entity-framework,entity-framework-migrations,entity-framework-4.3,Entity Framework,Entity Framework Migrations,Entity Framework 4.3,我一直在现有数据库上使用EntityFramework4.3,我有几个场景要考虑 首先,如果我删除了我的数据库,我想从头开始重新创建if-我已经成功地为此使用了CreateDatabaseIfNotExists数据库初始化器 其次,如果我更新了我的模型,并且数据库已经存在,我希望数据库能够自动更新——我已经成功地使用了EntityFramework4.3迁移 这是我的问题。假设我向模型中添加了一个新表,该表需要一些参考数据,这是确保在数据库初始化器运行和迁移运行时创建这些数据的最佳方法。我的愿望
非常感谢您的智慧。如果您想使用实体为数据种子,您应该在迁移配置中使用
seed
方法。如果生成新项目启用迁移
,您将获得以下配置类:
internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(CFMigrationsWithNoMagic.BlogContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
我不建议在
Up()
方法中使用Sql()
调用,因为(IMO)这实际上是针对没有内置函数的实际迁移代码,而不是种子代码
我喜欢将种子数据视为将来可能更改的内容(即使我的模式没有更改),因此我只需对种子函数中的所有插入内容编写“防御”检查,以确保操作之前没有触发
考虑这样一个场景:您有一个“Types”表,该表以3个条目开始,但随后添加了第4个条目。您不应该需要“迁移”来解决这个问题
使用Seed()
另外,请记住,对迁移代码和种子代码使用内置EF方法的好处是,您的数据库操作保持平台中立。这意味着您的模式更改和查询可以在Oracle、Postgre等上运行。如果您编写实际的原始SQL,则可能会不必要地锁定自己
您可能不太关心这一点,因为90%使用EF的人只会点击SQL Server,但我只是将其扔出去,让您对解决方案有一个不同的看法。您可以在Up方法中创建上下文,并使用AddOrUpdate插入行。但是,这不会包装在迁移事务中,因此可能会导致问题。此外,它也不能保证将来在模型更改时编译。我尝试在Up方法中创建上下文,但它抛出了一个错误,表示该表不存在。我将改用“Up”方法来尝试SQL。@Ladislav您对EF的深入了解继续让我感到惊讶,您是否考虑过就这个主题编写一本书,或者解决您在这里遇到的常见误解?使用此方法时,您必须小心设置AutomaticMigrationDataLossAllowed=false。如果不这样做,可能会丢失数据库中的数据。我在使用自动迁移时遇到了这种情况。最好使用seed方法。有没有从生产环境中调用该代码的方法?我不确定如何在目标服务器上进行最初的数据库种子设定。我需要创建一个角色(“管理员”),并确保其中有两个用户。我认为“Up”方法是一个进行“引用”数据的好地方—引用数据通常意味着应用程序需要该数据来进行某种逻辑。
public partial class SomeMigration : DbMigration
{
public override void Up()
{
...
Sql("UPDATE ...");
Sql("INSERT ...");
}
public override void Down()
{
...
}
}