实体框架Attach()对象树与共享对象 [英] Entity Framework Attach() object tree with shared objects

查看:103
本文介绍了实体框架Attach()对象树与共享对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public class Product 
{
public int ID;
public string Name;
public decimal成本;
}

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

public class Detail
{
public int Id;
公共产品产品;
public int数量;
}

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



是否有任何方式告诉EF对象上下文在Attach发生时重新使用跟踪的实体?请注意,我没有直接附加产品,所以像TryGetObjectStateEntry一样的技巧将无法正常工作。



任何建议?



编辑:



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



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

解决方案>

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

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

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


I am trying to attach an object tree to my Entity Framework context that was supplied via a WCF service call. The object in question has a collection of child items, and each child item has a property that is another tracked object type. However, there is only a small set of these last items, so most of the collection items share them. Something like this (except, obviously, with 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;
}

Whenever I have an Order that has more than one Detail for the same Product, the Entity Framework complains during the attach because it's trying to attach multiple copies of the same Product key. This information is coming in from a WCF ServiceOperation, so it's being deserialized as discrete instances of Product, even though in the client they are a set of shared objects.

Is there any way to tell the EF object context to re-use the tracked entities when the Attach happens? Note that I'm not attaching Products directly, so tricks like checking TryGetObjectStateEntry won't work.

Any suggestions?

EDIT:

I ran across the following article about self-tracking entities (which I have switched over to using), which includes a couple of client-side options that can be used as alternatives to Slauma's answer, which keeps the reconciliation code on the server side. (The self-tracking entities eliminate the need to use Attach() but the issue of duplicate keys still exists.)

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

解决方案

No, there is no way. You basically need to make the object references unique per key before you attach, something like:

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 maps key identities to object reference identities and it doesn't allow to have two or more objects with the same key in the context. Nor does it have a feature to make the references unique which would mean to select somehow one of your products with the same key as the correct product for that key. (You could have two products with the same key but different other properties. Which is the "correct" product for that key? EF refuses to decide that (and doesn't compare property by property if they all have identical values) and choses the easy and safe mode: throwing an exception.)

这篇关于实体框架Attach()对象树与共享对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆