使用LinqToSQL更新多对多关系

时间:2010-04-10 11:51:00

标签: .net linq-to-sql many-to-many

例如,如果我在用户和角色表之间有一个名为“RolesToUsers”的多对多映射表,我就是这样做的:

// DataContext is db, usr is a User entity
// newUserRolesMappings is a collection with the desired new mappings, probably 
//   derived by looking at selections in a checkbox list of Roles on a User Edit page
db.RolesToUsers.DeleteAllOnSubmit(usr.RolesToUsers);
usr.RolesToUsers.Clear();
usr.RolesToUsers.AddRange(newUserRolesMappings);

我曾经使用过SQL分析器,这似乎生成了非常智能的SQL - 它只会删除不再存在于映射关系中的行,并且只添加关系中尚不存在的行。正如我所想的那样,它不会盲目地完成关系的彻底清理和重建。

互联网在这个问题上非常安静,查询“LinqToSQL多对多”大多只是关于LinqToSQL数据映射器如何不能“支持”它的文章。

其他人如何使用LinqToSQL更新多对多?

2 个答案:

答案 0 :(得分:2)

关系是一组事实。 UsersRolesUsersToRoles都是关系,将一个人视为“一流”而不是另一个人是没有道理意义的。你正在做的事情很有道理,这就是为什么它似乎工作得很好。

ORM世界将关系模型比SQL更糟糕。特别是,它将关系数据库存储对象集合的谬误制度化。他们没有;他们存储了一系列事实。其中许多事实都是关于实体,这就是为什么谬误如此诱人。但是有很多其他类型的概念,例如会员资格,事件,状态,意见,交易,变更,比较,历史等等。

还要考虑:

  1. 在某些时候,您可能希望指明用户何时采用某个角色,然后可能指示该角色是待批准还是暂时撤销。我发现,我想在数据模型中表达的几乎所有“关系”最终都会携带超过构成多对多关系的两个外键的有效负载。如果您的OR映射已经设置为隐藏多对多(就像他们倾向于那样),那么您将发现在代码断裂方面向实体的过渡非常痛苦。
  2. 关系通常比二元更复杂。 “P教授在C班使用教科书T.”可能是一种不可简化的三元关系,它不容易隐藏在教授对象的某些集合属性之后。
    • 我刚刚注意到,几分钟前,这个问题恰好出现在SO question。从问题看来,JPA 2.0必须明确添加对三元关系的支持(它是否处理四元等关系?)。

答案 1 :(得分:1)

这可能不是你的问题的答案,而是解释为什么'互联网在这个问题上出奇的安静':我猜大多数人(包括我)只是更新/删除/添加单一 n-to-n关系的项目,因此永远不必问自己你的问题。

就像你有两个表'users'和'roles'一样,用例就是向用户添加/删除一个角色。

只是好奇:你需要在哪个应用程序中更新整个映射,就像你的例子一样?