如何在EF 6中部分更新导航属性?

时间:2017-08-08 14:56:33

标签: entity-framework navigation-properties

假设我有一个带子项的简单实体:

public class Entity
{
    public Guid ID { get; set; }
    public ICollection<Child> Children { get; set; }
}

public class Child
{
    public Guid ID { get; set; }
    public Guid ParentEntityID { get; set; }
}

&#34;儿童&#34;属性配置为一对多关系。下面有几个场景,我需要澄清会发生什么。

场景1:假设我加载了实体,但没有&#34;包括&#34;儿童财产:

  • 如果我然后将集合初始化为空列表并保存它...会消灭孩子还是什么都不做?我已经读过初始化集合是可选的,这表明将其初始化为空集是优秀的。但是,这与分配的集合表示相关对象的概念相矛盾,在这种情况下,分配空集会建议您清除相关对象。

场景2:假设我加载实体并且还包括&#34;包括&#34;儿童财产:

  • 如果我清除收藏并保存实体,那会消灭孩子吗?同样,因为它被包括在内,如果我分配一个新的空集,它会删除相关的对象吗?换句话说,当我包含导航属性vs不包括它时,是否分配新的空集并以不同方式保存实体函数?

场景3:假设我有成千上万的孩子,并想要添加或删除其中的一些:

  • 我是否必须&#34;包括&#34; (即预加载)整个集合以添加或删除项目?如果是这样,如何在不预先加载所有孩子的情况下执行该组的部分更新?

1 个答案:

答案 0 :(得分:0)

  

场景1:假设我加载实体但不“包含”子项   property:如果我然后将集合初始化为空列表并且   保存它......会消灭孩子还是什么都不做?

它什么都不做。没有孩子被装载,因此他们的状态都没有被跟踪。 EF实际上并不关心集合本身,只关心其中的内容。您甚至可以重新分配一个新的集合实例,只要将所有实体添加回其中,您就可以了。如果分离实体,您甚至可以从集合中删除实体,并且它们不会在数据库中受到影响。如果将它们全部分离,则可以将集合设置为null或空集合,它仍将保存更改而不会出现任何错误。它必须对子项执行某种闭环检查...看到它们的ParentID是X,它必须检查Parent X以查看该子项是否仍然在它的Children集合中,如果不是则抛出错误。它似乎将所有内容全部分析为跟踪实体的完整图表,并在加载内容时自动更新集合。这允许我做出一个预测,即如果我分别加载一个父项和一个子项并且Parent's Children集合为空,则应该导致错误。实际上,当我自己加载父项时,集合最初为null,然后当我自己加载一个或两个子项时,父项的子集合会被EF自动初始化/更新以包含已加载的子项,这样清除它将导致外键错误。

  

场景2:假设我加载实体并且还“包含”子项   property:如果我清除了集合并保存了实体,那就是   消灭孩子们?

是。 Include调用会将所有子项加载到跟踪器中。无论您是否提前初始化它,它都将确保它们全部属于Parent's Children系列。 “Include”调用实际上并没有使其功能有所不同,它只会让所有孩子都进入更改跟踪器。在加载父项之后单独加载所有子项最终会使整个系统处于与刚刚调用包含在前面的状态相同的状态。

  

场景3:假设我有成千上万的孩子并想要添加或   只删除其中几个:我必须“包括”(即预加载)   整个集合,以添加或删除项目?如果是的话,我该怎么办?   执行部分更新集而不预加载所有   儿?

绝对不是。您可以只加载要删除的那些,然后从DbSet中删除它们。如果您不想预先加载它们,可以对ID发出直接SQL删除语句。如果你没有调用include并且没有加载任何子项,那么你可以在集合导航属性中添加一些新的,只添加少数几个;其他所有不在变更跟踪器中的东西都是孤立的。