C# 向上迁移方法-实体框架中的更改数据
我已将新属性添加到现有模型中。这是一个bool属性,默认值为true。此表中存在现有数据,我希望在Up方法中创建新字段后,将一个特定行的新属性设置为falseC# 向上迁移方法-实体框架中的更改数据,c#,asp.net-mvc,entity-framework,entity-framework-migrations,C#,Asp.net Mvc,Entity Framework,Entity Framework Migrations,我已将新属性添加到现有模型中。这是一个bool属性,默认值为true。此表中存在现有数据,我希望在Up方法中创建新字段后,将一个特定行的新属性设置为false public override void Up() { AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false)); using (Context ctx = new Conte
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”上下文在创建数据库后已更改。
考虑使用代码第一迁移来更新数据库
是否可以在此处更改数据库或在其他位置更改数据库?在迁移过程中,最好使用
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\"");
}
在迁移过程中使用<代码> dBrave非常含糊。你期望从上下文中得到什么?它的模型中有迁移后状态,但数据库的表中有迁移前状态。因此,模型和数据库不匹配。如果您仍然坚持在代码中使用
DbContext
,禁用模型检查可能是解决方案。可以使用以下命令禁用模型检查:
Database.SetInitializer<Log4ProContext>(null);
Database.SetInitializer(null);
如果要使用框架进行类似的更改,应将数据库更改与数据更改分开
仅为数据库更改创建迁移,然后执行
然后创建一个新的迁移(Up()和Down()方法将为空)。您现在可以实例化DatabaseContext,不会出现错误。通过这种方式,您可以使用框架进行这些更改,并正确地实现Down()方法。为EF6编写数据迁移可能是一件麻烦事。我们建立了一个库,我只是在这里开放源码供其他人使用,它为EF6添加了这个长期承诺的、缺失的功能。只需使用常规EF查询等编写类
除了使用
Sql
方法,您还可以使用该方法
(我不知道是否只有ef core支持此方法)感谢您提供的解决方案以及缺少的defaultValue。当您找到您要查找的内容时,感觉非常好,您的朋友回答:)ef core从v2.1开始支持此功能这在ASP.NET core 3.1中正常工作。一个小的改进是尽可能使用nameof(例如nameof(RequestValidationErrors)、nameof(RequestValidationErrors.WordCode)、nameof(RequestValidationErrors,IsBreaking)。这个“解决方案”这是非常危险的,因为一开始它看起来很有效,但事实并非如此。一旦您随后创建了另一个迁移来更改数据库模型,它就不再有效,因为这样您就无法创建数据库上下文,因为模型不再支持数据库
migrationBuilder.UpdateData(
table: "RequestValidationErrors",
keyColumn: "WordCode",
keyValue: "RequestValidationError.MoreThanOneItemFound",
column: "IsBreaking",
value: false);