简体   繁体   English

当数据库似乎没有数据库时,为什么LINQ to SQL在Windows Phone上报告冲突?

[英]Why does LINQ to SQL report a conflict on Windows Phone, when the database doesn't appear to have one?

I've got a web service that is returning objects for me, along with a candidate key, which I've marked up with: 我有一个Web服务正在为我返回对象,以及一个我已标记为的候选键:

[Column(IsPrimaryKey = true)]
public int EventId { get; set; }

All is fine with loading the data back from the webservice, but whilst iterating through the new & updated items to put them in a SQL CE database to act as a cache, like so: 一切都很好,可以将数据从Web服务加载回去,但是同时遍历新的和更新的项目以将它们放入SQL CE数据库中以充当缓存,如下所示:

foreach (var e in results)
{
    var ev = (from evt in context.Events where evt.EventId == e.EventId select evt).FirstOrDefault();
    if (ev == null)
    {
        // Brand new
        context.Events.InsertOnSubmit(e);
    }
    else
    {
        // Update data
        ...
    }
}

For some reason, it occasionally thinks an event is brand new but it throws an exception during the InsertOnSubmit : 由于某种原因,它偶尔会认为一个事件是全新的,但是在InsertOnSubmit期间会引发异常:

System.InvalidOperationException was unhandled 未处理System.InvalidOperationException

Cannot add an entity that already exists. 无法添加已经存在的实体。

I've pulled the database off of the emulator with the Windows Phone Power Tools, loaded the database up in Visual Studio, and there doesn't seem to be any conflicting value for the primary key, so why am I getting an exception that implies there is a conflict, and the debugger shows there aren't any cross-thread issues? 我已使用Windows Phone Power Tools将数据库从仿真器中拉出,并在Visual Studio中加载了数据库,并且主键似乎没有任何冲突的值,所以为什么我得到一个异常提示,发生冲突,并且调试器显示没有任何跨线程问题?

EDIT 编辑

One thing I did spot, is that my entity has an overridden Equals() that didn't cover the primary key (it did a comparison on a natural key), and it appears the web service has two records on something that is documented as a candidate key. 我发现的一件事是,我的实体具有一个覆盖的Equals() ,该Equals()不覆盖主键(它对自然键进行了比较),并且该Web服务似乎在某个东西上记录了两个记录,记录为候选密钥。

If I adjust the Equals method to account for the primary key as well, the exception changes to be a SqlCeException and it tells me that: 如果我也调整Equals方法来解决主键问题,则该异常更改为SqlCeException ,它告诉我:

A duplicate value cannot be inserted into a unique index. 重复值不能插入唯一索引。 [ Table name = SpecialEvent,Constraint name = PK_SpecialEvent ] [表名称= SpecialEvent,约束名称= PK_SpecialEvent]

Even though the primary key still hasn't been duplicated, which leaves me more confused (especially, as that type of exception cannot be easily caught) 即使主键仍然没有被复制,这也让我更加困惑(特别是因为这种类型的异常不容易被捕获)

EDIT2 EDIT2

I've even tried using a lock() {} around the code performing the update, but I'm still getting odd conflicts, so I'm confused why I'm occasionally getting conflicts, especially when the SDF doesn't reflect the same conflicts. 我什至尝试在执行更新的代码周围使用lock() {} ,但是我仍然遇到奇怪的冲突,所以我很困惑为什么偶尔会遇到冲突,尤其是当SDF无法反映冲突时。同样的冲突。

In my case, it turns out that it was down to a couple of factors combining -- my entities did not have a property with IsVersion = true nor did they have UpdateCheck = UpdateCheck.Never on columns that did not make up part of my primary key. 就我而言,这IsVersion = true两个因素-我的实体没有IsVersion = true的属性,也没有UpdateCheck = UpdateCheck.Never 。键。 It appears there was a timing issue which was resulting in it trying trying to update only when the columns matched what it was expecting the old values to be. 似乎存在计时问题,导致它仅在列与预期的旧值匹配时才尝试尝试更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM