代码优先 - 当我没有将父对象设置为 EntityState.Modified 时,如何保存 ICollection?

2023-12-28

如果我有以下课程:

public class Foo()
{
public int PropertyIWantUpdated {get; set;}
public int PropertyIDontWantUpdated (get; set}

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

当保存到我的数据库时,而不是

context.Entry(thisFoo).State = EntityState.Modified;

我在用着

context.Entry(thisFood).Property(tf => tf.PropertyIWantUpdated).IsModified = true;

我怎样才能保存对条形图的更改?


这取决于您要尝试更新的内容。首先让我澄清一个重要的事实 - 如果您有分离的实体图(更多具有关系的实体)并且您想要将所有更改传递给 EF,您有责任告诉 EF 每个实体和每个关系中发生了什么更改 - EF 不会帮助你。

如果您只是尝试更新Bar实例并且您没有更改关系(=您没有添加新的Bar to Foo或删除Bar from Foo)你只需要迭代Bars并将它们设置为Modified state.

如果您还更改了内容Bars收集整个过程变得非常复杂,方法取决于您定义实体的方式=如果您正在使用独立或外键关联 https://stackoverflow.com/questions/5281974/code-first-independent-associations-vs-foreign-key-associations/5282275#5282275.

如果是外键关联(Bar将 FK 作为属性 = inBar你有类似的东西FooId)您遵循与开始时类似的方法。你迭代Bars并将状态设置为:

  • Modified如果现有的Bar被分配给Foo
  • Added如果一个新的Bar被分配给Foo

有一个大问题。如果你删除了一些Bar实例来自Bars集合,您还必须将它们附加到上下文并相应地设置它们的状态:

  • Modified如果 FK 应设置为 null
  • Deleted if Bar应该删除

这一切仅适用于一对多关系。

如果您认为以前的方法很复杂,请准备好在独立关联的情况下(Bar没有 FK 属性 - 对于多对多关系总是如此)这个过程甚至更糟。独立关联有自己的对象跟踪状态 = 设置状态Bar实体不保留新的关系。第一个问题是这个对象不能直接从 DbContext API 访问 - 你必须转换DbContext to ObjectContext并使用ObjectStateManager获得访问权限ObjectStateEntry代表关系。之后,您必须正确设置其状态,这并不像看起来那么容易,因为关系不能处于Modified状态 - 它只能处于Unchanged, Added or Deleted。这意味着如果您将 Bar 的关系从一种更改为另一种Foo您必须首先找到旧关系并将其设置为已删除,然后才能将新关系设置为添加。如果您有多对多关系,并且还想添加、删除和更新相关对象(不仅仅是关系),这可能真的很“有趣”——尤其是您必须在某处保存已更改的信息这一事实能够正确设置所有状态。

关于这个问题的更多讨论(EF中的全局)是here https://stackoverflow.com/questions/3635071/update-relationships-when-saving-changes-of-ef4-poco-objects/3635326#3635326- 它与 DbContext API 无关,但因为新 API 只是旧 ObjectContext API 的包装,所以仍然存在相同的问题。

您认为可行吗?我不这么认为。因此,您应该尽量避免这种情况。有一些方法可以避免它:

  • 对附加对象图进行更改 - 这意味着您将首先将实体图的原始状态附加到上下文,然后进行所有更改。
  • 加载原始对象图并手动将新图的所有更改合并到已加载(和附加)的对象图。
  • 如果是 ObjectContext API,您可以使用自跟踪实体 https://stackoverflow.com/questions/5091974/what-is-the-purpose-of-self-tracking-entities/5092097#5092097它们能够跟踪状态并自动设置应用于上下文的所有内容。他们还有一些其他的缺点 https://stackoverflow.com/questions/3814706/self-tracking-entities-vs-poco-entities/3815968#3815968和限制(例如,它们不支持延迟加载),并且它们不适用于 DbContext API。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代码优先 - 当我没有将父对象设置为 EntityState.Modified 时,如何保存 ICollection? 的相关文章

随机推荐