在迁移中更改数据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查询等编写类。

https://github.com/b9chris/Brass9.Data

您也可以使用UpdateData方法,而不是使用Sql方法。

 migrationBuilder.UpdateData( table: "RequestValidationErrors", keyColumn: "WordCode", keyValue: "RequestValidationError.MoreThanOneItemFound", column: "IsBreaking", value: false); 

(我不知道是否只有ef核心支持这种方法)