删除具有未加载子实体的实体

Posted

技术标签:

【中文标题】删除具有未加载子实体的实体【英文标题】:Deleting an entity that has an un-loaded child entity 【发布时间】:2010-11-19 01:54:32 【问题描述】:

我需要对 Entity Framework 中的级联删除进行一些澄清,尽管搜索了几个小时并没有更接近解决方案。

简而言之,如果我有一个实体 (MyObject) 与一个孩子 (MyObjectDetail) 有 1->0..1 关系,那么如果没有 UpdateException 抱怨约束,我就无法删除 MyObject - 但是 仅当子 MyObjectDetail 未加载到内存中时。

System.Data.UpdateException:正在从 AssociationSet 'FK_MyObjectDetail_MyObject' 添加或删除关系。使用基数约束,还必须添加或删除相应的“MyObjectDetail”。

如果孩子已加载(即删除 MyObject 之前的 MyObject.MyObjectDetailReference.Load()),那么它可以正常工作。

当然,我的问题是,我不想(阅读:不能)每次我想删除父 MyObject 时都从 MyObjectDetail 加载 varbinary 字段。这可能吗,还是我将不得不手动执行一些 SQL 调用来完成这项工作?

在 SQL 服务器中:

MyObject [PK:Id] -> MyObjectDetail [PK:MyObjectId, Data]

关系设置为“级联”以进行更新和删除。

在 EF 设计器中:

MyObject [1] -> [0..1] MyObjectDetail

在 EF XML 中:

SSDL:

完> 校长> 依赖> 参考约束> 联想>

CSDL:

完> 依赖> 参考约束> 联想>

(CSDL中的是我根据http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/之类的文章手动添加的)

我做错了什么,或者这在 EF 的 v1 中根本不可能?

【问题讨论】:

【参考方案1】:

EF 依赖于数据库进行级联删除。

例外情况是子实体在内存中。然后EF也会删除它,而不是满足级联删除规则。而是因为它需要这样做以使 ObjectContext 与在数据库中删除 Principal 后它期望数据库的外观保持同步。

这意味着如果您在数据库中没有级联设置,并且未加载依赖实体,则在您删除原则时 EF 不会删除它们,因为它假设数据库会这样做。

更多信息请参见Tip 33 - How cascade delete really works。

这有帮助吗?

亚历克斯·詹姆斯

实体框架团队

【讨论】:

那么,我们需要做出哪些改变才能让这种情况“正常工作”?【参考方案2】:

我认为您可以通过使用相关对象的 id 更新 myObject.myPropertyReference = new EntityKey 来解决此问题。类似于:

myObject.myPropertyReference.EntityKey = EFExtensions.GetEntityKey(context, "myObjectID", myObject.myObjectID);

搜索 EFExtension .. 你不需要这个,因为有一种方法可以在没有它的情况下创建 EntityKey。

希望有帮助!

【讨论】:

太棒了。这完全符合我的要求 - 谢谢!我只使用了 EFExtensions 而不是:EntityKey = new EntityKey("MyEntities.MyObjectDetailSet", "MyObjectId", id)【参考方案3】:

This blog entry 实际上引用 this 问题作为它提出解决方案的问题的示例。

【讨论】:

以上是关于删除具有未加载子实体的实体的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 - 连接新添加的 Poco 实体并加载子对象(插入/添加)

删除与基于视图的实体具有一对多关联的实体对象

删除具有一对多关系的实体

核心数据:删除最后一个具有一对多关系的实体

iOS:删除核心数据中具有一对多关系的实体

HIbernate 无法删除具有外键的实体。外键设置为空