简体   繁体   English

实体框架 - 具有多对多表的用户和组

[英]Entity Framework - Users and Groups with Many to Many tables

I have run into an issue that has me going around in circles.我遇到了一个让我绕圈子的问题。 What I need to implement is users and groups in our website.我需要实现的是我们网站中的用户和组。 We are using Entity Framework (database first) with ASP.NET in C#.我们在 C# 中将实体框架(数据库优先)与 ASP.NET 一起使用。

Here are the requirements:以下是要求:

  1. There are users有用户
  2. There are groups (which are created by the administrator and will exist in the DB)有组(由管理员创建并将存在于数据库中)
  3. Each users can be in one or more groups每个用户可以属于一个或多个组
  4. Each group can have 0 or more users.每个组可以有 0 个或多个用户。

The current Groups are: Administrator Board of Directors Editors当前的组是: 管理员 董事会 编辑

So in short, "User1" can be in both the Editor & Board of Directors groups but not a member of the Administrator group.简而言之,“User1”可以同时属于 Editor 和 Board of Director 组,但不能属于 Administrator 组。

First I constructed my database with a Users, a Groups and a UserGroups table.首先,我用一个用户、一个组和一个用户组表构建了我的数据库。 The userGroups table has the following fields: userGroups 表具有以下字段:

 User Group ----------- ------------ UserId (PK) GroupId (PK) Name Name ... ... \\ / UserGroup ------------- UserGroupTestID (PK) UserId (FK) GroupId (FK)

The problem with this approach is that EF will not let me add more than 1 user to this table throwing a "Multiplicity constraint violated" error since it was a 1 User to Many relationship.这种方法的问题在于 EF 不会让我向该表添加 1 个以上的用户,从而引发“违反多重约束”错误,因为它是 1 个用户对多的关系。

So I changed it to be a many-to-many table by dropping the PK as follows:因此,我通过删除 PK 将其更改为多对多表,如下所示:

User              Group
-----------       ------------
UserId (PK)       GroupId (PK)
Name              Name
...               ...

       \           /
          UserGroup
         -------------
          UserId (FK)
          GroupId (FK)

I was now able to access user.Group and was able to add a group to this user.我现在能够访问 user.Group 并且能够向该用户添加一个组。 When I was adding a user to a group, I was querying the existing groups and adding it like this:当我将用户添加到组时,我正在查询现有组并像这样添加它:

user.Groups.Add( ctx.Groups.Where( g => g.GroupID == 12 ).First( ); user.Groups.Add( ctx.Groups.Where( g => g.GroupID == 12 ).First( );

The problem is that this created a new group for this user in the Groups table - even though the ID of the Group was correct (12) when it was saved to the database.问题是这在 Groups 表中为该用户创建了一个新组 - 即使组的 ID 在保存到数据库时是正确的 (12)。

I need to do the following things:我需要做以下事情:

  1. Create a user and put the new user in 1 or more groups.创建一个用户并将新用户放入 1 个或多个组中。
  2. Edit an existing user to add or remove them from groups.编辑现有用户以在组中添加或删除他们。

I am sure that I am doing something wrong (and probably bone-headed), but if anyone can help me to achieve this, I would really appreciate it.我确信我做错了什么(并且可能是愚蠢的),但如果有人能帮助我实现这一目标,我将不胜感激。

Thanks in advance!提前致谢!

Code in Admin_AddUser.aspx.cs: Admin_AddUser.aspx.cs 中的代码:

User user = new User( );
user.CustomerID = CustomerID;
user.IsClub = false;
user.IsDistrict = true;
user.FirstName = txtFirstName.Text;
user.LastName = txtLastName.Text;
user.Email = txtEmail.Text;
user.Password = txtPassword.Text;
user.AccountActive = true;

foreach( RadListBoxItem item in lbSelectedRoles.Items )
{
  user.Roles.Add( UserData.GetRole( DCManager.Instance.SiteSettings.Customer.CustomerID, int.Parse( item.Value ) ) );
}

bool rtn = UserData.CreateUser( user );
...

Code in CreateUser method: CreateUser 方法中的代码:

public static bool CreateUser( User user )
{
  using ( var ctx = new DCEntities( ) )
  {
    //Check if the login credentials already exist
    if ( ctx.Users.Where( u => u.Email == user.Email
                           && u.Password == user.Password ).Count( ) > 0 )
      return false;
    else
    {
      ctx.Users.Add( user );
      ctx.SaveChanges( );

      return true;
    }
  }
}

========================= ==========================

In my project, the Groups and actually called "Roles"在我的项目中,组实际上称为“角色”

Since the UserGroups table in the DB is a many-to-many, it is not show in the EDMX file, but the Users & Groups (Roles in my db) are linked as many-to-many.由于数据库中的 UserGroups 表是多对多的,它没有显示在 EDMX 文件中,但用户和组(我的数据库中的角色)是多对多链接的。对象

Mapping Details:映射细节:

用户映射详细信息角色映射详细信息

If I understood your question correctly.如果我正确理解你的问题。 I would recommend you do the following:我建议您执行以下操作:

  1. Create a table UsersAndGroups (int: PK, UserId: FK, GroupId: FK).创建一个表 UsersAndGroups (int: PK, UserId: FK, GroupId: FK)。
  2. Establish relationships between Users and UsersAndGroups as one-to-many.将 Users 和 UsersAndGroups 之间的关系建立为一对多。
  3. Establish relationships between Groups and UsersAndGroups as one-to-many.在 Groups 和 UsersAndGroups 之间建立一对多的关系。
  4. Remove relationship between Users and Groups.删除用户和组之间的关系。

This will allow you the following:这将允许您执行以下操作:

  1. Add User to one or more groups by adding rows to UsersAndGroups table.通过向 UsersAndGroups 表添加行来将用户添加到一个或多个组。
  2. Get User groups by selecting all records with certain UserId from UsersAndGroups table.通过从 UsersAndGroups 表中选择具有特定 UserId 的所有记录来获取用户组。
  3. Get Group users by selecting all records with certain GroupId from UsersAndGroups table.通过从 UsersAndGroups 表中选择具有特定 GroupId 的所有记录来获取组用户。

Hope I understood you right.希望我理解你正确。

Using code first:首先使用代码:

To Roles add到角色添加

public virtual List<User> Users { get; set; }

To Users add给用户添加

public virtual List<Role> Roles { get; set; }

Your classes might look like this您的课程可能如下所示

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;


namespace MyProject.EFTest
{
    public class Role
    {
        [Key]
        public int RoleID { get; set; }

        [Required]
        [StringLength(100)]
        public string Name { get; set; }

        public virtual List<User> Users { get; set; }

    }

    public class User
    {
        [Key]
        public int UserID { get; set; }

        public string Name { get; set; }

        public virtual List<Role> Roles { get; set; }

    }

}

When the migration is generated EF will create table UserRole in addition to Users and Roles生成迁移时,EF 将创建表 UserRole 以及 Users 和 Roles

    CreateTable(
        "dbo.UserRole",
        c => new
            {
                User_UserID = c.Int(nullable: false),
                Role_RoleID = c.Int(nullable: false),
            })
        .PrimaryKey(t => new { t.User_UserID, t.Role_RoleID })
        .ForeignKey("dbo.User", t => t.User_UserID)
        .ForeignKey("dbo.Role", t => t.Role_RoleID)
        .Index(t => t.User_UserID)
        .Index(t => t.Role_RoleID);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM