在迁移中更改数据Up方法 – entity framework
我在现有模型中添加了一个新属性。 它是一个bool属性,默认值为true。 此表中存在现有数据,我想在Up方法中创建新字段后立即将一个特定行的新属性设置为false。
public override void Up() { AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false)); using (Context ctx = new Context()) { var validation = ctx.RequestValidationErrorSet.FirstOrDefault(x => x.WordCode == "RequestValidationError.MoreThanOneItemFound"); if (validation != null) { validation.IsBreaking = false; ctx.SaveChanges(); } } }
这样,EF在说话时抛出错误
System.InvalidOperationException:自创建数据库以来,支持’DbContext’上下文的模型已更改。 考虑使用Code First Migrations来更新数据库
是否可以在此更改数据库,还是应该在其他地方更改数据库?
在迁移过程中,最好使用Sql()
方法更新数据库数据。
Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = 'RequestValidationError.MoreThanOneItemFound'");
您还应该为新列定义默认值。 所以解决方案应该是这样的:
public override void Up() { AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false, default: true)); Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = \"RequestValidationError.MoreThanOneItemFound\""); }
在它的迁移过程中使用DbContext
是非常模糊的。 您对上下文的期望是什么? 它在模型中具有迁移后状态 ,但数据库在表中具有迁移前状态 。 所以模型和数据库不匹配。 如果仍然坚持在代码中使用DbContext
,则禁用模型检查可能是解决方案。 您可以使用以下方法禁用模型检
Database.SetInitializer(null);
如果要将框架用于此类更改,则应将数据库更改与数据更改分开。
仅为数据库更改创建迁移,然后执行。
然后创建一个新的迁移(Up()和Down()方法将为空)。 您现在可以实例化DatabaseContext,并且不会出现错误。 这样,您可以使用Framework进行这些更改,并正确实现Down()方法。
为EF6编写DataMigrations可能是件苦差事。 我们把一个我刚刚开放的图书馆放在一起供其他人使用,这为EF6提供了这个长期承诺的缺失function。 只需使用常规EF查询等编写类。
您也可以使用UpdateData
方法,而不是使用Sql
方法。
migrationBuilder.UpdateData( table: "RequestValidationErrors", keyColumn: "WordCode", keyValue: "RequestValidationError.MoreThanOneItemFound", column: "IsBreaking", value: false);
(我不知道是否只有ef核心支持这种方法)