Linq to Sql:没有抛出ChangeConflictException(并且没有更新/删除行)

时间:2010-12-30 14:52:46

标签: linq-to-sql concurrency n-tier-architecture

我正在尝试将Linq与Sql结合成N层设计。我通过在将对象附加到数据上下文时提供原始值来实现并发。当调用SubmitChanges并观察sql server profiler上生成的脚本时,我可以看到它们正在正确生成。它们包括检查所有对象属性的where子句(它们都标有UpdateCheck.Always)。

结果符合预期,即更新时不更新行或删除时删除行。但我没有任何例外。这不应该抛出ChangeConflictException吗?

为了清楚起见,我正在运行的测试的设计和流程:我有一个客户端控制台和一个服务控制台,通过WCF使用WsHttpBinding相互通信。

  1. 客户请求服务中的数据
  2. Service实例化datacontext,检索数据,处理上下文,将数据返回给客户端。
  3. 客户端对返回的数据进行修改。
  4. 客户请求从服务更新已更改的数据 5A。服务实例化datacontext,附加对象和...
    5B。我暂停执行并更改数据库中的值以引起更改冲突 5C。服务调用SubmitChanges。
  5. 这是第5步的代码,为清晰起见清理了一下:

    public void UpdateEntities(ReadOnlyChangeSet<Entity> changeSet)
            {
                using (EntityDataContext context = new EntityDataContext())
                {
                    if (changeSet.AddedEntities.Count > 0)
                    {
                        context.Entities.InsertAllOnSubmit(changeSet.AddedEntities);
                    }
    
                    if (changeSet.RemovedEntities.Count > 0)
                    {
                        context.Entities.AttachAll(changeSet.RemovedEntities, false);
                        context.Entities.DeleteAllOnSubmit(changeSet.RemovedEntities);
                    }
    
                    if (changeSet.ModifiedRecords.Count > 0)
                    {
                        foreach (var record in changeSet.ModifiedRecords)
                        {
                            context.Entities.Attach(record.Current, record.Original);
                        }
                    }
    
                    // This is where I pause execution and make changes to the database
    
                    context.SubmitChanges();
                }
            }
    

    我正在使用一些类来跟踪更改并维护原件,如您所见。

    任何帮助表示感谢。

    编辑:我对插入没有任何问题。我只包含调用InsertAllOnSubmit以获得完整性的代码。

1 个答案:

答案 0 :(得分:0)

所以我找到了答案。它似乎是Linq To Sql中的一个错误(如果我错了,请纠正我)。事实证明,数据库中正在更新的表上有一个触发器。此触发器调用具有返回值的存储过程。这会导致调用此表上的插入,更新或删除以产生返回值(来自触发器运行的存储过程),该值不是行计数而是数字。显然,L2S看到了这个数字并假设一切顺利,即使实际上没有插入/更新/删除。

这很奇怪,特别是考虑到返回的数字有一个已定义的列名,其值在6位数区域内。