好的,所以你认为你是一个真正的调试器?试试这个:
我有一个 Linq2Sql 项目,突然我们发现偶尔,看似随机,我们会得到同一行的双插入。
我已经继承DataContext
和覆盖了SubmitChanges
. 在里面,我在调用GetChangeSet()
之前和之后都调用了base.SubmitChanges()
,并使用文本文件记录器来记录Inserts
集合中的对象。另外,我保留对插入对象的引用足够长的时间来记录它们的自动编号 ID。
当双插入发生时,我在数据库中看到,不是每行都插入到MyTableA
andMyTableB
中,而是每行有两行。SQL Profiler 显示四个插入语句,一个接一个地快速连续:
insert into MyTableA(...
insert into MyTableB(...
insert into MyTableA(...
insert into MyTableB(...
我检查了调试日志,集合中只有两个对象Inserts
:一个和一个。在调用 之后,变更集是空的(应该是)。并且自动编号 ID 显示新插入行的较大值。MyClassA
MyClassB
base.SubmitChanges()
另一条有用的信息:在调试模式下单步执行时永远不会发生错误;仅当您在没有断点的情况下运行时。这让我怀疑这与执行速度有关。
我们已经使用同一DataContext
个子类一年多了,而且我们以前从未在我们的产品中看到过这种行为。它只发生在MyClassA
andMyClassB
上。
总结一下:
- 从调试日志来看,一切看起来都正常。
- 在 SQL Profiler 上,您可以看到正在发生双插入。
- 这种行为经常发生,但出乎意料,只发生在提到的两个类中,除了在调试模式下单步执行代码时它从不发生。
编辑 - 新信息:
在我的DataContext
子类中,我有以下代码:
try {
base.SubmitChanges(ConflictMode.ContinueOnConflict);
} catch (ChangeConflictException) {
// Automerge database values for members that client has not modified.
foreach (ObjectChangeConflict occ in ChangeConflicts) {
occ.Resolve(RefreshMode.KeepChanges);
}
}
// Submit succeeds on second try.
base.SubmitChanges(ConflictMode.FailOnFirstConflict);
MyTableA
并且MyTableB
两者都有一个强制性的外键OtherTableID
引用OtherTable
。双重插入发生在ChangeConflictException
公共父表更新期间发生的情况下OtherTable
。
我们闻到气味了,现在...