实体框架:多个代码优先迁移和配置种子方法
本文关键字:迁移 配置 种子 子方法 框架 代码 实体 | 更新日期: 2023-09-27 18:13:41
我正在向实体框架代码优先迁移的表添加一列。我读到你可以在Configuration.cs
中使用Seed
方法,它将在更新数据库运行时播种数据。如果您有多个迁移,该如何工作?一个迁移可能需要播种一些数据,另一个迁移可能需要播种其他数据。配置文件中只有一个Seed
方法。如何防止实体框架在将来添加更多迁移时多次播种相同的数据?是否直接删除配置文件中Seed
方法的内容?
我知道这有点晚了,但我遇到了这个答案,并对它不满意。经过一些修改,这里有一个替代的解决方案。
执行如下命令:
add-migration YourSchemaMigration
update-database
add-migration YourDataMigration
这应该构建并应用您的模式更改,然后第二个add-migration调用应该为您构建一个空的迁移。而不是使用迁移来添加或删除字段或表,在那里打开一个DbContext并开始删除数据
public partial class YourDataMigration : DbMigration
{
public override void Up()
{
// Importing from CSV
using(db = new FooDbContext())
ImportUtil.ImportFoos(db, "initial_foo_data.csv"));
}
public override void Down()
{
// Nothing!
}
}
运行Update-Database
时,将DbContext
作为参数传递给Seed方法。你可以对上下文做任何你想做的事情,包括查询数据库以查看已经存在的数据,并确保你的Seed方法是幂等的。
例如,如果数据库不存在管理员,您可能希望始终确保数据库始终以管理员播种…
protected override void Seed(MyDbContext context)
{
if (!context.Users.Any(u => u.Username == "administrator"))
{
var user = new User { Username = "administrator", PasswordHash = "hashed password" };
context.Users.Add(user);
context.SaveChanges();
}
}
我将currentVersion
的变量存储在我的数据库中,并将其与新版本进行比较并执行升级操作。它的工作原理类似于以下代码。如果currenVersion
比newVersion
老,UpgradeVersion()
将执行升级操作。如果currentVersion
等于或更新于newVersion
,则UpgradeVersion()
不执行任何操作。
protected override void Seed(MyDbContext 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" }
// );
//
UpgradeVersion(context, 100, null);
UpgradeVersion(context, 101, (ver) => { /*do upgrade actions to version 101 */ });
UpgradeVersion(context, 102, (ver) => { /*do upgrade actions to version 102 */ });
}
private void UpgradeVersion(MyDbContext context, int newVersion, Action<int> upgradeAction) {
// If newVersion > currentVersion, call upgradeAction(newVersion) and set currentVersion to newVersion
// Else, return directly and do nothing.
}