代码之家  ›  专栏  ›  技术社区  ›  Mark Lindell

如何在n层场景中利用EF4.0Poco自跟踪实体的并发性检查?

  •  1
  • Mark Lindell  · 技术社区  · 14 年前

    我正在使用VS1010RC和POCO自我跟踪T4模板。

    在我的WCF更新服务方法中,我使用的是类似于以下内容的内容:

    using (var context = new MyContext())
    {
      context.MyObjects.ApplyChanges(myObject);
      context.SaveChanges();
    }
    

    在我在实体上设置concurrencyMode=fixed,然后我得到一个异常之前,这是可以正常工作的。当SQL语句在WHERE子句中使用已更改的实体值时,上下文似乎不知道前面的值。

    当使用concurrencyMode=fixed时,正确的方法是什么?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Craig Stuntz    14 年前

    前面的值需要在对象中。

    假设你有财产 ConcurrencyToken :

    public class MyObject
    {
        public Guid Id { get; set; }
        // stuff
        public byte[] ConcurrencyToken { get; set; }
    }
    

    现在你可以设置 ConcurrencyMode.Fixed 在那块地产上。您还需要配置数据库以自动更新它。

    当您查询数据库时,它将具有一些值:

    var mo = Context.MyObjects.First();
    Assert.IsNotNull(mo.ConcurrencyToken);
    

    现在可以分离或序列化对象,但需要包括 并发令牌 .因此,如果要将对象数据放到Web窗体上,则需要序列化 并发令牌 把它放到一个隐藏的输入中。

    当你 ApplyChanges ,您需要包括 并发令牌 :

    Assert.IsNotNull(myObject.ConcurrencyToken);
    using (var context = new MyContext())
    {
      context.MyObjects.ApplyChanges(myObject);
      context.SaveChanges();
    }
    

    并发模式。已修复 改变了 UPDATE SQL。通常看起来像:

    UPDATE [dbo].[MyObject]
    SET --stuff
    WHERE [Id] = @0
    

    并发模式。已修复 看起来像:

    UPDATE [dbo].[MyObject]
    SET --stuff
    WHERE [Id] = @0 AND [ConcurrencyToken] = @1
    

    …因此,如果有人在您读取原始并发令牌的时间和您保存的时间之间更新了行,那么 更新 将影响0行而不是1行。在这种情况下,EF会引发并发错误。

    因此 ,如果其中任何一项对您不起作用,第一步是使用SQL事件探查器查看生成的 更新 .

        2
  •  0
  •   KoenJ    14 年前

    作记号,

    创建为“自跟踪实体”的对象不能视为纯POCO;

    原因如下: 只有当您的客户机使用ste t4模板生成的代理时,stes才能很好地工作。 更改跟踪,因此您的服务,将只与这些生成的代理一起工作。

    在纯POCO世界中(互操作性,不是所有的.NET 4.0客户端,…),你不能放 对客户的约束。例如,Facebook不会写一个可以 仅处理.NET 4.0客户端。

    在某些环境中,STES可能是一个不错的选择,这完全取决于您的需求。