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

发布于 2024-11-25 05:13:31 字数 499 浏览 4 评论 0原文

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

用户

  • ID
  • 用户名
  • 密码

角色

  • ID
  • 名称
  • 说明

UserRoles

  • UserID
  • RoleID

UserRoles 是一个用于模拟多对多关系的查找表。向该表添加记录允许将用户和角色中的记录关联起来。我的问题是,在实体框架中,它正确地将其解释为多对多关系并抽象出该查找表。

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

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

I have three tables in my sample database:

Users

  • ID
  • Username
  • Password

Roles

  • ID
  • Name
  • Description

UserRoles

  • UserID
  • RoleID

UserRoles is a lookup table to simulate a many to many relationship. Adding records to this table allows one to associate records in Users and Roles. My problem is that in Entity Framework it correctly interprets this as a many to many relationship and abstracts away that lookup table.

This works great most of the time, but I'm not sure what to do when I want to add/delete entries from that lookup table. I can delete roles or users but that actually deletes the objects not just their association with each other.

I do know of one option to add a dummy column to the UserRoles lookup table. That will force Entity Framework to turn the lookup table into a full-blown entity, allowing me to add and remove them as lone objects. But I have no need for a dummy column and this seems like a hack. I am looking for better suggestions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

独闯女儿国 2024-12-02 05:13:31

它应该看起来像这样:

删除关系

user.Roles.Remove(existingRoleEntity);

添加关系

user.Roles.Add(existingRoleEntity);

It should look something like this:

To Remove Relationship

user.Roles.Remove(existingRoleEntity);

To Add Relationship

user.Roles.Add(existingRoleEntity);
枉心 2024-12-02 05:13:31

您可以在实体上使用导航属性:(

假设 u 是用户对象):

using (var db = new UserEntities())
{
    Role roleToRemove = db.Roles.Single(SelectRoleHere);
    User user = db.Users.Single(SelectUserHere);
    user.Roles.Remove(roleToRemove);
    db.SaveChanges();
}

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

You can use the navigation properties on the entities:

(assuming u is a User object):

using (var db = new UserEntities())
{
    Role roleToRemove = db.Roles.Single(SelectRoleHere);
    User user = db.Users.Single(SelectUserHere);
    user.Roles.Remove(roleToRemove);
    db.SaveChanges();
}

EDIT - Added SaveChanges based on Slauma's comment.

策马西风 2024-12-02 05:13:31

我之前已经解决了这个问题,只需将私钥标识符自动增量列添加到查找表中,因为实体框架将始终隐藏仅包含 2 列且末表具有外键的查找表。有时您需要通过实体框架直接添加查找条目,这将帮助您实现这一目标。

问题作者的更新

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

http://www.codetunnel.com/content/images /ManyToManyDynamic.jpg

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

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);

这需要更多的工作,但除非有相当于user.Roles.Remove(role) (类似于 user.Roles.Associate(existingRoleEntity)),那么这是我唯一的选择。

更新:

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);

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

I have solved this problem before by simply adding an Private Key Identifier Auto-Increment column to the lookup table as Entity Framework will always hide lookup tables that only contain 2 columns with foreign keys to the end tables. Sometimes you need to add a lookup entry directly yourself via Entity Framework and this will help you achieve that.

Update From Question Author

I just wanted to provide an update on my own implementation of this answer. I added an identity column to the lookup table and created a unique key over the two foreign key columns to prevent duplicate relationship entries in the table. My model now looks like this:

http://www.codetunnel.com/content/images/ManyToManyDynamic.jpg

The only thing that sucks is to get a collection of all associated Roles I would have to do this:

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);

It's a little more work but unless there is an equivalent to user.Roles.Remove(role) (something like user.Roles.Associate(existingRoleEntity)) then this is my only option.

Update:

List<Role> roles = new List<Role>();
foreach (UserRole userRole in myUser.UserRoles)
    roles.Add(userRole.Role);

Can be achieved via:

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

You can always use a public partial class to extend User to have a property to return all roles using the above. Click the link for details of the public partial class stuff I gave on another question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文