H. *_*her 33 linq entity-framework entity-framework-4
我使用实体框架4,我与"级联删除"设置有父子关系.所以当我调用SaveChanges()时,当我从父母中删除孩子时,我会期望删除孩子.
cuRepository.Attach(_controlUnit);
foreach (var recipe in recipes) {
_controlUnit.Recipes.Remove(recipe);
//repository.DeleteObject(recipe);
}
Run Code Online (Sandbox Code Playgroud)
相反,我得到一个错误:
发生System.InvalidOperationException消息=操作失败:无法更改关系,因为一个或多个外键属性不可为空.当对关系进行更改时,相关的外键属性将设置为空值.如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象.
当我明确删除子项(请参阅注释行)时,一切都很好.我错过了什么?
Amy*_*y B 28
您没有使用remove语句删除该对象.相反,您试图更改记录并使其成为孤立(通过将外键设置为null).数据库在该列上具有非空约束,并阻止您这样做.
Chr*_*ris 26
假设您有类设计,如下所示:

实体框架将生成所需的外键列并NOT NULL为它们添加约束,因为所有配方将始终与一个ControlUnit关联.
因此,在运行时,您将拥有类似于以下布局的对象:

现在您的代码发挥作用并删除了Recipe对象与其ControlUnit之间的关系:

此时尝试保存,数据库没有要放入外键NOT NULL列的ControlUnit ID .当前对象状态违反了上面的类图,并且无法保存到在假设每个Recipe与一个ControlUnit关联的情况下生成的数据库布局中.这就是数据库拒绝保存更改并看到异常的原因.
这也解释了当您取消注释删除实体的行时它的工作原理:实体与数据库及其关系一起被删除,因此没有违反约束,因此没有例外.
"但我开始ON DELETE CASCADE关系......"
是的,但这仅在删除对象时触发,而不是在删除关系时触发.使用ON DELETE CASCADEset,这应该工作:
controlUnitRepository.DeleteObject(_controlUnit);
// deletes the ControlUnit and all associated Recipe entities
Run Code Online (Sandbox Code Playgroud)
如果要在删除与ControlUnit的关系时触发删除配方实体,则您的关系不应该是简单的关联,而应该是一个组合:

EF本身不支持此功能,但您可以使用标识关系来模拟行为.一旦实体处于与父实体的识别关系中并且该关系被移除,该实体也将被移除.从一开始,这似乎是你的意图.有关识别关系的更多信息,请参阅实现与EF4的识别关系,其中我实现了与EF4的识别关系,并链接到更多阅读材料.
如果您将child和parent之间的关系设置为标识关系,则可以从集合中删除子实体.您需要将子密钥作为包含父级主ID的组合密钥.那样EF知道它需要移除孩子.
识别关系基本上说如果父母不存在那么孩子没有意义.这意味着EF知道在删除关系时删除子项是安全的.
请参阅此问题识别关系并插入子实体会导致"无法为表中的标识列插入显式值",这一个是否可以从集合中删除子项并解决SaveChanges上的问题?
| 归档时间: |
|
| 查看次数: |
28016 次 |
| 最近记录: |