LINQ-to-SQL和多对多关系删除

我在两张桌子之间有多对多的关系,让我们说朋友和食物。 如果朋友喜欢食物,我会在FriendsFoods表中添加一行,如下所示:

ID Friend Food 1 'Tom' 'Pizza' 

FriendsFoods分别有一个主键’ID’和两个非空外键’Friend’和’Food’到’Friends’和’Foods’表。

现在假设我有一个Friend tom .NET对象对应’汤姆’,汤姆不再喜欢披萨(他怎么了?)

 FriendsFoods ff = tom.FriendsFoods.Where(x => x.Food.Name == 'Pizza').Single(); tom.FriendsFoods.Remove(ff); pizza.FriendsFoods.Remove(ff); 

如果我尝试在DataContext上提交SubmitChanges() ,我会得到一个exception,因为它试图在FriendsFoods表的Friend and Food列中插入一个null。

我敢肯定我可以整理一些复杂的逻辑来跟踪对FriendsFoods表的更改,拦截SubmitChanges()调用等尝试SubmitChanges()按照我想要的方式工作,但有一个很好的,干净的方法来删除与LINQ-To-SQL的多对多关系?

假设数据库本身在外键上定义了CASCADE DELETE规则(否则您遇到了麻烦),您需要在Linq to SQL设计器(或AssociationAttributeDeleteRuleDeleteRule每个关系的删除规则设置为CASCADE

您也不需要删除关联的两面 – 一个就足够了,无论是来自tom还是来自pizza

附录: @Crispy也是正确的,因为您关注的真实属性是子关联中的DeleteOnNull属性。 但是 ,您无法在设计器中看到这一点的原因是设计器根据(a)父 – 子关联的CASCADE设置自动检测此属性的值,以及(b)是否是外键字段可以为空。 如果在Linq to SQL设计器中有一个带有CASCADE DELETE的非可空FK,它应该自动为子到父关联设置DeleteOnNull = true ,然后从映射表中删除该记录,而不是尝试设置其关联为NULL

如果你试图通过从linq实体的FriendFoods删除它来从多对多表( FriendFoods )中删除该条目,则需要在DeleteOnNull中将关系上的DeleteOnNull属性设置为true文件。 不幸的是,你不能通过dbml设计器来做到这一点。 您必须将.dbml文件作为xml文件打开,然后手动编辑该关联的xml。

请参阅如何从LINQ to SQL中删除子集合中的记录?

CASCADE DELETE不适用于此处。 它仅适用于删除实体的情况,即Friend对象或Food对象,但如果您只是想删除关系则不适用。 您是否有任何理由不直接访问关系表? 我认为这将是一个更清洁的解决方案。