http://weblogs.asp.net/zeeshanhirani/archive/2010/07/23/removing-entity-from-a-related-collection.aspx解释到底发生了什么,以你的内心。
假设你有一个一流的设计是这样的:
实体框架将生成所需的外键列,并添加NOT NULL
约束他们,因为所有的食谱总是以完全相同相关一个ControlUnit。
所以在运行时,你将有类似于以下布局对象:
现在你的代码进场,并删除了配方之间的关系的对象和他们的控制单元:
试图保存在这个时候,数据库没有一个ControlUnit ID放入外键NOT NULL
列。当前对象状态违反了上面的类图,并且无法将其保存到假设每个配方都与一个ControlUnit关联的情况下生成的数据库布局。这就是数据库拒绝保存更改并看到异常的原因。
这也解释了为什么它在解除删除实体的行时注释掉:实体从数据库及其关系中删除,因此没有违反约束,因此没有例外。
“但我的关系设置ON DELETE CASCADE
...”
是的,但这只是引发了对象的删除,不上关系的缺失。随着ON DELETE CASCADE
集,这应该工作:
controlUnitRepository.DeleteObject(_controlUnit);
// deletes the ControlUnit and all associated Recipe entities
如果要触发配方实体删除它们与控制单元关系的缺失,你们的关系不应该是简单关联,而是一个组成:
EF本身不支持此操作,但可以使用标识关系来模拟行为。一旦实体处于与父实体的识别关系并且该关系被移除,该实体也被移除。看起来这是你一开始的意图。有关确定关系的更多信息,请参阅Implementing identifying relationships with EF4,其中我实施了与EF4的识别关系并已链接到更多阅读材料。
public static void Delete<T>(this EntityCollection<T> collection, T entityToDelete) where T : EntityObject, IEntityWithRelationships
{
RelationshipManager relationshipManager = entityToDelete.RelationshipManager;
IRelatedEnd relatedEnd = relationshipManager.GetAllRelatedEnds().FirstOrDefault();
if (relatedEnd == null)
{
throw new Exception("No relationships found for the entity to delete. Entity must have at least one relationship.");
}
var query = relatedEnd.CreateSourceQuery() as ObjectQuery;
if (query == null)
{
throw new Exception("The entity to delete is detached. Entity must be attached to an ObjectContext.");
}
query.Context.DeleteObject(entityToDelete);
collection.Remove(entityToDelete);
}
所以我然后删除实体像Order.Products.Delete(prod)
:
今天我有同样的问题,我相信这是在实体框架设计缺陷。 SQL Server中的表之间的关系声明“级联删除孤儿”,因此应该可以工作。它在NHibernate中的工作方式。幸运的是,您可以按照GraemeMiller的回答和相关问题开展工作。 – 2013-04-22 10:38:04