【问题标题】:EF optimistic concurrency exceptions need to fixEF 乐观并发异常需要修复
【发布时间】:2015-05-07 06:17:03
【问题描述】:

大家好,所以我在互联网上尝试了一些想法来解决这个问题,但都失败了,所以我为什么要写这个,所以也许有人可以在实体框架最新版本中帮助我:)

 using (var ctx = new ESContext())
            {
                quote =
                      ctx.HB_Quote.FirstOrDefault(x => x.ID == issuesContract.EvidenceContract.QuoteContract.ServerID) ??
                      new ESModel.HB_Quote()
                      {
                          ID = issuesContract.EvidenceContract.QuoteContract.ServerID ?? 0,
                          QuoteLegend = issuesContract.EvidenceContract.QuoteContract.QuoteLegend,
                          QuoteText = issuesContract.EvidenceContract.QuoteContract.QuoteText
                      };
                if (issuesContract.EvidenceContract.QuoteContract.ServerID == null)
                {
                    ctx.HB_Quote.Add(quote);
                }
                else
                {
                    ctx.Entry(quote).State = EntityState.Modified;
                }
                ctx.SaveChanges();
            }
            using (var ctx = new ESContext())
            {
                imageLibrary =
                       ctx.HB_ImageLibrary.FirstOrDefault(
                           x => x.ID == issuesContract.EvidenceContract.ImageLibaryContract.ServerID) ??
                       new ESModel.HB_ImageLibrary()
                       {
                           ID = issuesContract.EvidenceContract.ImageLibaryContract.ServerID ?? 0,
                           Conclusion = issuesContract.EvidenceContract.ImageLibaryContract.Conclusion,
                           Image = issuesContract.EvidenceContract.ImageLibaryContract.Image,
                           Title = issuesContract.EvidenceContract.ImageLibaryContract.Title
                       };
                if (issuesContract.EvidenceContract.ImageLibaryContract.ServerID == null)
                {
                    ctx.HB_ImageLibrary.Add(imageLibrary);
                }
                else
                {
                    ctx.Entry(imageLibrary).State = EntityState.Modified;
                }
                ctx.SaveChanges();
            }

最后一部分 co 使用了这个错误:

EntityFramework.dll 中出现“System.Data.Entity.Infrastructure.DbUpdateConcurrencyException”类型的异常,但未在用户代码中处理

附加信息:存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=472540

【问题讨论】:

    标签: c# database entity-framework orm


    【解决方案1】:

    Paul 的分析(在预期的地方更新了零行)对我来说似乎是正确的。通常,此错误的原因是一个所谓的 TimeStamp 字段,该字段用于捕获并发问题(两个用户彼此独立但同时编辑同一行的情况)。那么,HB_ImageLibrary 表中是否有任何字段标记为 TimeStamp,属于 Fixed?

    数据库和实体之间的关系是什么?模型优先,数据库优先,代码优先?

    【讨论】:

      【解决方案2】:

      乍一看,我认为这段代码在第一个 using 块中引起了您的问题(以及第二个块中的类似代码):

      else
      {
          ctx.Entry(quote).State = EntityState.Modified;
      }
      

      此时,在您的代码中,您已从 EF 检索到一条有效记录,但您尚未对其进行任何操作。现在您明确告诉 EF 它已被修改,这意味着它会在您调用 SaveChanges() 时尝试更新它。它希望从数据库中获取更新的行数 == 1,但实际上没有更新任何行,因此它的计数为 0,从而导致您的错误。

      EF 擅长为您跟踪更改,您很少需要这种级别的状态管理 (See here for a little bit more info)。删除这些代码块应该可以解决您的问题。

      【讨论】:

      • 但是当它是其他方式时,只需添加它更改 quote.ID + 1 然后保存为新对象知道为什么吗?
      • 我认为您的代码可能会让您有些混乱,quote 可能是两件事之一,要么是从数据库中获取的实体,在这种情况下,EF 应该自动跟踪其更改,并且更新现有行。或者,如果没有找到,quote 是在内存中创建的新对象,在这种情况下,无论您如何编辑它,EF 都会将其保存为数据库中的新行。试着做一个简单的 fetch-edit-save 看看它的行为是否符合你的预期。
      • 所以澄清一下,你是:
      • 如果quote 是在内存中创建的,由于?? 运算符,您的代码很难分辨,那么您对quote 的属性进行多少更改都没有关系,当您调用 SaveChanges() 时,quote 将作为新行插入。如果分配quote!= null 的查询,则EF 应跟踪您对quote 所做的任何更改,并在您调用SaveChanges() 时更新现有行。如果这不是正在发生的情况,请尝试进行一个非常简单的交互,例如 var testObj = ctx.HB_Quote.First(x => x.ID == 6); testObj.ID = 8; ctx.SaveChanges();,并验证它是否按预期工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多