gpt4 book ai didi

c# - 开箱即用地更新 EF 中的子集合真的不可能吗(又名非 hacky 方式)?

转载 作者:可可西里 更新时间:2023-11-01 08:44:09 25 4
gpt4 key购买 nike

假设您的实体中有这些类。

public class Parent
{
public int ParentID { get; set; }
public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
public int ChildID { get; set; }
public int ParentID { get; set; }
public virtual Parent Parent { get; set; }
}

并且您有一个用户界面来更新 Parent 及其 Children,这意味着如果用户添加新的 Child 那么您必须插入,如果用户编辑了一个现有的 Child 那么你需要更新,如果用户删除了一个 Child 那么你必须删除。现在很明显,如果您使用以下代码

public void Update(Parent obj)
{
_parent.Attach(obj);
_dbContext.Entry(obj).State = EntityState.Modified;
_dbContext.SaveChanges();
}

它将无法检测到 Child 内的更改,因为 EF 无法检测到导航属性内的更改。

我已经问了大约 4 次这个问题,得到的答案不一。那么,实际上有可能在不变得复杂的情况下做这些事情吗?这个问题可以通过在 ParentChild 之间分离用户界面来解决问题,但我不想这样做,因为合并了 Child父级在一个菜单中在业务应用程序开发中很常见,并且更加用户友好。

更新:我正在尝试下面的解决方案,但它不起作用。

public ActionResult(ParentViewModel model)
{
var parentFromDB = context.Parent.Get(model.ParentID);

if (parentFromDB != null)
{
parentFromDB.Childs = model.Childs;
}

context.SaveChanges();
}

EF 不会检测 Children 内部的变化,而是无法判断如何处理旧的 child。例如,如果 parentFromDB 在我第一次从数据库中拉出它时有 3 个 child ,那么我删除第二个和第三个 child 。然后我得到 The relationship couldn't be changed because a or more of the foreign-key properties is non-nullable 保存时。

我相信这就是发生的事情: The relationship could not be changed because one or more of the foreign-key properties is non-nullable

这让我回到原点,因为在我的场景中,我不能只从数据库中获取并更新条目并调用 SaveChanges

最佳答案

because EF cannot detect changes inside Navigation Property

这似乎是对 _dbContext.Entry(obj).State = EntityState.Modified 没有将导航属性标记为已修改这一事实的描述。

当然,EF 会跟踪导航属性的变化。它跟踪附加到上下文的所有实体的属性和关联的变化。因此,您的问题的答案现在是肯定的……

Is it possible to update child collection in EF out of the box

...是:

唯一的问题是:您不能开箱即用

更新任何实体的“开箱即用”方式,无论它是某个集合中的父实体还是子实体:

  • 从数据库中获取实体。
  • 修改他们的属性或向他们的集合中添加/删除元素
  • 调用SaveChanges()

就是这样。 Ef 跟踪更改,您永远不会显式设置实体 State

但是,在断开连接(n 层)的情况下,这会变得更加复杂。我们对实体进行序列化和反序列化,因此没有任何上下文可以跟踪它们的变化。如果我们想要将实体存储在数据库中,现在我们的任务是让 EF 知道更改。基本上有两种方法可以做到这一点:

  • 根据我们对实体的了解手动设置状态(例如:主键 > 0 表示它们存在并且应该更新)
  • 绘制状态:从数据库中检索实体并将反序列化实体的更改重新应用到它们。

当涉及到关联时,我们总是必须描绘状态。我们必须从数据库中获取当前实体并确定添加/删除了哪些子项。无法从反序列化对象图本身推断出这一点。

有多种方法可以减轻绘制状态这一枯燥而复杂的任务,但这超出了本问答的范围。一些引用:

关于c# - 开箱即用地更新 EF 中的子集合真的不可能吗(又名非 hacky 方式)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33056482/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com