2012-04-26 80 views
8

使用实体框架代码首先,我有这样的:为什么设置EntityState分离清空类型列表的属性<T>?

public class Foo 
{ 
    public int Id { get; set; } 

    public List<Bar> Bars { get; set; } 
}  

Foo foo = (from f in ctx.Foos.Include("Bars") where f.Id == 42 select f).Single(); 

// At this point foo.Bars is populated 

ctx.Entry(foo).State = EntityState.Detached; 

// At this point foo.Bars is an empty List 

为什么分离对象的原因,而是财产public List<string> Bars,这是明确的,并成功列入,被掏空?

分离可能具有许多属性的对象的正确过程是什么?

回答

9

之所以被清空列表是在实体框架两条规则的组合:

  1. 当你只分离此对象本身没有对象被分离的对象的任何导航属性参考。

  2. ObjectContext/DbContext不允许保存部分附加到上下文并部分分离的对象图。尽管在使用POCOs时可能会发生临时状态,但EF会始终通过在各种方法(如AddAttach,设置实体的状态等)中的图形中自动附加分离的对象来修复此临时状态,或者当SaveChanges叫做。

这意味着,当你从上下文中分离根对象,EF将明确儿童的名单,因为:a)子女保持连接(规则1)和b)在分离和连接对象的组合该图不被允许(规则2)。

据我所知,在保持原始树结构的同时,无法从上下文中分离对象图。您可以依次分离父母和孩子。因此,您已经从上下文中分离了树的所有对象,但树同时被销毁 - 每个导航属性都是无效的。

手动分离实体的主要目的是在存在内存资源限制且不希望并且需要在上下文中保存大量对象的情况下将它们释放以进行垃圾回收。为此目的,图结构被破坏并不重要。

我不知道为什么你需要从上下文中分离对象。但请记住,也可以选择从数据库加载实体,而不必将它们附加到上下文中,例如使用AsNoTracking()

关于与MSDN文档一些参考问题的另一个答案就在这里:https://stackoverflow.com/a/7693732/270591

+0

的的DbContext超出我的目标是不断设置前不久范围。使用'AsNoTracking()'加载我的对象允许收集DbContext,还是我的对象仍然保持对它的引用?这是我最关心的问题。 – 2012-04-27 01:19:20

+0

@EricJ .:您首先使用EF代码,因此您的实体是POCO。如果你不使用延迟加载(并且它看起来不是'Foo.Bars'不是'virtual'),那么实体不是代理,并且它们没有对上下文的引用。所以,答案是肯定的,即使你仍然持有对你的实体的引用,上下文将被垃圾收集。 – Slauma 2012-04-27 10:54:02

+0

如果实体是代理,那么上下文将不会被垃圾收集,直到实体被处置? – 2012-04-27 19:02:12

相关问题