entity-framework - 如何部分更新 EF 6 中的导航属性?

标签 entity-framework navigation-properties

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

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; }
}

“Children”属性配置为一对多关系。在下面的几个场景中,我需要说明会发生什么。

场景 1:假设我加载实体但不“包含”Children 属性:

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

场景 2:假设我加载实体并“包含”Children 属性:

  • 如果我清除集合并保存实体,是否会消灭子项?同样,既然它被包括在内,如果我分配一个新的空集,它会删除相关的对象吗?换句话说,当我包含导航属性与不包含它时,分配一个新的空集和保存实体功能是否不同?

场景 3:假设我有数千个子级并且只想添加或删除其中的几个:

  • 我是否必须“包含”(即预加载)整个集合才能添加或删除项目?如果是这样,我如何在不预加载所有子项的情况下执行集合的部分更新?

最佳答案

Scenario 1: Assume I load the entity but don't "Include" the Children property: If I then initialize the collection to an empty list and save it... will that wipe out the children or do nothing?

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

Scenario 2: Assume I load the entity and also "Include" the Children property: If I clear the collection and save the entity, would that wipe out the children?

是的。 Include 调用会将所有子项加载到跟踪器中。它将确保它们都在 Parent 的 Children 集合中,无论您是否提前初始化它。 “Include”调用并没有真正使它的功能有任何不同,它只是让所有的 child 进入更改跟踪器。在加载父项之后单独加载所有子项最终会将整个系统置于相同的状态,就好像您刚刚预先调用了 include 一样。

Scenario 3: Assume I have thousands of Children and want to add or remove just a few of them: Do I have to "Include" (i.e. preload) the entire collection in order to add or remove items? If so, how can I perform a partial update of the set without preloading all the children?

绝对不是。您可以只加载要删除的那些,然后将它们从 DbSet 中删除。如果您不想预先加载它们,您可以对 ID 发出直接的 SQL 删除语句。如果您不调用 include 并且不加载任何子项,那么您可以只向集合导航属性添加几个新的,并且只会添加这几个;不在更改跟踪器中的所有其他内容都保持不变。

关于entity-framework - 如何部分更新 EF 6 中的导航属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45571712/

相关文章:

c# - 使用数据库上下文时如何指定连接字符串

c# - WPF 有条件地启用键绑定(bind)

entity-framework - 使用 Entity Framework 和 where 查询而不创建大量查询(避免 N+1)

c# - 使用 Include(string) 方法包含多个导航属性

c# - Code First 默认 DateTime 不工作

asp.net-mvc - 找不到类型或命名空间名称 'DbContext'

c# - EF : Include navigation property and exclude sub navigation property in same time

c# - EF 避免将导航属性附加到 DTO

c# - 如何在运行时使用 Entity Framework 动态添加/删除字段?

.net - Windows 窗体数据绑定(bind)和属性路径 : how to handle nullability?