【问题标题】:Updating every item in a table with Linq / C#使用 Linq / C# 更新表中的每个项目
【发布时间】:2023-03-26 11:16:01
【问题描述】:

我正在尝试在我的 EF 代码优先配置的 Seed() 方法中将所有包含 http: 的 url 替换为 https:。我有以下内容:

var context = new DbContext(); // contains public DbSet<Doc> Docs { get; set; }
var docs = context.Docs.ToList();  // dbcontext

foreach (var doc in docs)
{
    if (doc.ImageContent != null && doc.ImageContent.Contains("https:"))
        doc.ImageContent = doc.ImageContent.Replace("https:", "http:");
}
context.saveChanges

但是每当我运行它时(从我的数据库迁移中的种子方法 - 所以据我所知我无法调试) - 我收到以下错误:

System.Data.DataException: An exception occurred while initializing the database. See the InnerException for details. ---> System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. 

即使我注释掉 SaveChanges,也会出现此错误。该字段只是一个非必需的字符串,所以我认为验证不会由于不正确的数据类型而失败......它还能是什么?

【问题讨论】:

  • 除了问题,你可能忘记了context.Entry(doc).State = EntityState.Modified
  • @AlbertoLeón - 刚刚尝试过,得到了同样的错误
  • 像这样的 saveChanges 之后是否有括号... _db.SaveChanges();问题不是问题,因为您注释掉了该行。您也可以尝试使用 NuGet 让 NLog 帮助调试,这就是我调试播种的方式。

标签: c# .net linq entity-framework ef-code-first


【解决方案1】:

我认为您应该将代码更改为此

foreach (var doc in context.Docs)

由于var docs = context.Docs.ToList(); 将拉取内存中的所有对象,并且上下文无法跟踪任何更改。

【讨论】:

  • 我不敢相信这会有所作为。 context.Docs.ToList() 获取的对象也会被跟踪。
  • 同意 Gert,除非你使用了投影,.Configuration.AutoDetectChangesEnabled = false;或 Context.Set().AsNoTracking()
  • 感谢 cmets。我将在今天晚些时候再看一下这个问题。
【解决方案2】:

您应该能够对符合特定条件的任何记录执行更新。而不是拉整个列表缩小结果集。

var context = new DbContext(); // contains public DbSet<Doc> Docs { get; set; }

foreach (var doc in context.Docs.Where(d => d.ImageContent.StartsWith("https:")))
{
    doc.ImageContent = doc.ImageContent.Replace("https:", "http:");
}

context.SaveChanges();

【讨论】:

  • 这是一个比公认答案更好的解决方案,因为它只从数据库中提取真正需要更新的文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多