“SubmitChanges()”上的LINQ to SQL“1/2更新失败”

时间:2009-12-14 06:34:32

标签: c# sql-server linq-to-sql

我正在使用LINQ to SQL更新类型为X的对象及其子Y,然后提交更改并收到此错误

示例代码

X objX = _context.X.ToList().Where(x => x.DeletedOn == null).First();
objX.DeletedOn = DateTime.Now;

EntitySet<Y> objYs = objX.Ys;
Y objY = objYs[0];
objY.DeletedOn = DateTime.Now;

_context.SubmitChanges();

在SubmitChanges()上,我得到一个例外“1 of 2 Updates failed”,没有其他信息说明为什么会发生这种情况。有什么想法吗?

异常类型也是 ChangeConflictException

4 个答案:

答案 0 :(得分:11)

Sooo问题的原因是什么 - 触发器

我做了一个sql profiler并看到了

当ObjY的DeletedOn属性更新后,触发器更新 ObjX的属性(表中的值)称为CountOfX

导致错误,因为LINQ to SQL创建的SQL中包含旧的CountOfX值。

因此发生了冲突。

如果您收到此错误 - SQL分析器是开始调查的最佳位置

与问题无关 我正在测试LINQ to SQL和ADO.net Framework,奇怪的是这个错误发生在LINQ to SQL而不是ADO.net框架中。但我喜欢LINQ to SQL for Lazy Loading。等待EF获得测试结果

答案 1 :(得分:2)

我不确定错误的原因究竟是什么,但是您提供的示例似乎存在许多问题。

  • 在Where()方法之前使用ToList()会导致上下文将整个表从DB读入内存,将其转换为数组;然后在同一行中,您立即调用Where将丢弃您已加载的行,但不需要。为什么不呢:

    _context.X.Where(...

  • Where方法将返回多个项目,但示例中的第二行似乎没有单独迭代每个项目。它似乎是为集合本身设置DeletedOn属性,但该集合不具有这样的属性。它应该在那里失败。

  • 您在代码中使用了DateTime.Now两次。没问题,除了每次调用它时会产生如此微小的日期值。您应该调用DateTime.Now一次并将结果分配给变量,以便您使用它的所有内容都具有相同的值。

  • 如果您有“Y objY = objYs [0]”,如果Y集合中没有任何给定X的项目,它将失败。您将获得一个索引超出范围的例外阵列。

所以在这个例子中,我不确定是否有人可以推测为什么在这个例子之后建模的代码可能会破坏。

答案 2 :(得分:2)

在LINQ2SQL数据上下文关系图中,选择实体和存储计数的字段。 (非规范化的数字)

现在设置UpdateCheck =从不。

答案 3 :(得分:0)

我有这样的问题。我一次调试运行单行。事实证明,另一个进程正在修改此记录。

我的手动调试过程正在减慢功能的正常速度。当我在SubmitChanges方法之后将它一直运行到一行时,它成功了。

我的场景不太常见,但此错误的性质与记录被另一个函数/进程取代有关。就我而言,这是另一个过程。