C# 在实体框架中添加/删除多对多关联

C# 在实体框架中添加/删除多对多关联,c#,.net,entity-framework,entity-framework-4,entity-relationship,C#,.net,Entity Framework,Entity Framework 4,Entity Relationship,我的示例数据库中有三个表: 使用者 身份证 用户名 密码 角色 身份证 名字 描述 用户角色 用户ID 罗莱德 UserRoles是一个用于模拟多对多关系的查找表。将记录添加到此表中可以关联用户和角色中的记录。我的问题是,在实体框架中,它正确地将其解释为多对多关系,并抽象出该查找表 这在大多数情况下都很有效,但我不确定当我想从查找表中添加/删除条目时该怎么做。我可以删除角色或用户,但这实际上会删除对象,而不仅仅是它们之间的关联 我知道有一个选项可以向UserRoles查找表添加虚拟列

我的示例数据库中有三个表:

使用者
  • 身份证
  • 用户名
  • 密码
角色
  • 身份证
  • 名字
  • 描述
用户角色
  • 用户ID
  • 罗莱德
UserRoles是一个用于模拟多对多关系的查找表。将记录添加到此表中可以关联用户和角色中的记录。我的问题是,在实体框架中,它正确地将其解释为多对多关系,并抽象出该查找表

这在大多数情况下都很有效,但我不确定当我想从查找表中添加/删除条目时该怎么做。我可以删除角色或用户,但这实际上会删除对象,而不仅仅是它们之间的关联


我知道有一个选项可以向UserRoles查找表添加虚拟列。这将迫使实体框架将查找表转换为完整的实体,允许我将它们作为单独的对象添加和删除。但是我不需要一个虚拟的专栏,这看起来像是一个黑客。我在寻找更好的建议。

应该是这样的:

解除关系 添加关系
您可以在实体上使用导航属性:

(假设u是用户对象):


EDIT-根据Slauma的评论添加了SaveChanges。

我以前解决过这个问题,只需在查找表中添加一个私钥标识符自动递增列,因为
实体框架
将始终隐藏仅包含两列外键的查找表。有时您需要通过
实体框架
直接添加查找条目,这将帮助您实现这一点

问题作者更新 我只是想提供一个关于我自己实现这个答案的更新。我向查找表中添加了一个标识列,并在两个外键列上创建了一个唯一键,以防止表中出现重复的关系项。我的模型现在看起来像这样:

唯一糟糕的是获取所有关联角色的集合我必须这样做:

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);
可通过以下方式实现:

IEnumerable<int> roleIDs = myUser.UserRoles.Select(r => r.RoleID);
IEnumerable<Role> roles = Entityies.Roles.Where(r => roleIDs.Contains(r.roleID);
IEnumerable roleIDs=myUser.UserRoles.Select(r=>r.RoleID);
IEnumerable roles=entityes.roles.Where(r=>roleIDs.Contains(r.roleID));

您始终可以使用来扩展
用户
以拥有一个属性来返回使用上述内容的所有角色。单击链接以获取我在另一个问题上提供的
公共部分类
内容的详细信息。

我没有考虑将虚拟列设为PK标识符列。这样做似乎不是多余的。我确实需要添加和删除因此,将其变成一个实体是有意义的。答案很好!@Alex Ford:你真的用这种方式破坏了多对多关系。你必须引入一个新的人工实体,然后建立两个1对多关系。EF中多对多关系中的联接表应该隐藏在模型中。@Slauma,这样做确实允许你添加多个用户并向其添加角色的情况下,将角色解压缩到
用户
。直接添加角色可能很有用,在更复杂的情况下可能需要添加。@Slauma,我知道我破坏了抽象。但是,这只是执行
用户.UserRoles.Single(某些条件)的额外步骤.Role
并使我能够添加和删除关系。除非您能够提供一种在维护抽象的同时将关系添加到查找表中的方法,否则这是我唯一的选择。这样做还允许您多次将相同的
角色添加到
用户
,而这并不是真正的建模多对多关系非常好。除非您有要附加到关系的特定信息,否则请坚持实体框架的设计方式。有关如何添加关系的信息,请参阅我文章中的注释。因此,我也会这样做,再加上SaveChanges():)这很好,但如何添加关系?@Alex Ford:替换
。删除
。添加
。明白了,我不知道这一点。我刚刚在我的示例应用程序中测试了它。工作出色!如何将条目添加到查找表中?@Alex:方法相同,但使用
add
而不是
Remove
user.Roles.Add(role)
role.Users.Add(user)
.Aha!我没有意识到这一点。这实际上是我们想要的更好的解决方案。
using (var db = new UserEntities())
{
    Role roleToRemove = db.Roles.Single(SelectRoleHere);
    User user = db.Users.Single(SelectUserHere);
    user.Roles.Remove(roleToRemove);
    db.SaveChanges();
}
List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);
List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);
IEnumerable<int> roleIDs = myUser.UserRoles.Select(r => r.RoleID);
IEnumerable<Role> roles = Entityies.Roles.Where(r => roleIDs.Contains(r.roleID);