9

首先使用实体​​框架代码,我有类似的东西:

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明确且成功包含的属性被清空?

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

4

1 回答 1

14

列表被清空的原因是实体框架中的两个规则的组合:

  1. 当你分离一个对象时,只有这个对象本身被分离,没有任何导航属性引用的对象。

  2. ObjectContext/DbContext不允许保存部分附加到上下文并部分分离的对象图。虽然这可能在使用 POCO 时作为临时状态发生,但 EF 将始终通过在各种方法(如AddAttach、设置实体的状态等)或最近SaveChanges调用时自动附加图表中的分离对象来修复此临时状态。

这意味着当您从上下文中分离根对象时,EF 将清除子对象列表,因为:a) 子对象保持连接状态(规则 1)和 b) 不允许在图中混合分离和附加对象(规则2)。

据我所知,在保持原始树结构的同时,无法将对象图从上下文中分离出来。您可以将父级分离,然后将子级一个接一个地分离。结果,您已将树的所有对象从上下文中分离出来,但树同时被销毁 - 每个导航属性都无效。

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

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

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

于 2012-04-27T00:22:59.873 回答