【问题标题】:Entity Framework Attach() object tree with shared objects具有共享对象的实体框架 Attach() 对象树
【发布时间】:2011-12-07 14:58:58
【问题描述】:

我正在尝试将对象树附加到通过 WCF 服务调用提供的实体框架上下文。有问题的对象有一个子项的集合,每个子项都有一个属性,该属性是另一个被跟踪的对象类型。但是,这些最后的项目只有一小部分,因此大多数集合项目都共享它们。像这样的东西(显然,EntityObjects 除外):

public class Product
{
  public int Id;
  public string Name;
  public decimal Cost;
}

public class Order
{
  public int Id;
  public List<Detail> details;
}

public class Detail
{
  public int Id;
  public Product Product;
  public int Quantity;
}

每当我的订单包含同一产品的多个详细信息时,实体框架会在附加期间抱怨,因为它试图附加同一产品密钥的多个副本。此信息来自 WCF ServiceOperation,因此它被反序列化为 Product 的离散实例,即使在客户端它们是一组共享对象。

有没有办法告诉 EF 对象上下文在 Attach 发生时重新使用被跟踪的实体?请注意,我没有直接附加产品,因此检查 TryGetObjectStateEntry 之类的技巧将不起作用。

有什么建议吗?

编辑:

我遇到了以下关于自我跟踪实体的文章(我已转而使用),其中包括几个客户端选项,可用作 Slauma 的答案的替代方案,它将协调代码保留在服务器端。 (自跟踪实体消除了使用 Attach() 的需要,但仍然存在重复键的问题。)

http://blogs.msdn.com/b/diego/archive/2010/10/06/self-tracking-entities-applychanges-and-duplicate-entities.aspx

【问题讨论】:

    标签: wcf entity-framework


    【解决方案1】:

    不,没有办法。在附加之前,您基本上需要使每个键的对象引用唯一,例如:

    void PrepareForAttach(Order order)
    {
        var dict = new Dictionary<int, Product>();
        foreach (var detail in order.Details)
        {
            Product firstProduct;
            if (dict.TryGetValue(detail.Product.Id, out firstProduct))
                detail.Product = firstProduct;
            else
                dict.Add(detail.Product.Id, detail.Product);
        }
    }
    

    EF 将键标识映射到对象引用标识,并且它不允许在上下文中有两个或多个具有相同键的对象。它也没有使引用唯一的功能,这意味着以某种方式选择您的产品之一,其密钥与该密钥的正确产品 相同。 (您可以拥有两个具有相同密钥但其他属性不同的产品。哪个是该密钥的“正确”产品?EF 拒绝决定(如果它们都具有相同的值,则不会逐个比较属性)并选择简单安全模式:抛出异常。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 2017-02-07
      • 2011-11-05
      • 1970-01-01
      • 2011-11-26
      • 2011-03-04
      相关资源
      最近更新 更多