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

时间:2015-01-09 21:03:24

标签: c# sql-server database entity-framework

我遇到了一个让我绕圈子走的问题。我需要实现的是我们网站中的用户和群组。我们在C#中使用Entity Framework(数据库优先)和ASP.NET。

以下是要求:

  1. 有用户
  2. 有一些组(由管理员创建,将存在于数据库中)
  3. 每个用户可以在一个或多个群组中
  4. 每个组可以有0个或更多用户。
  5. 目前的群组是: 管理员 董事会 编辑

    简而言之,“User1”可以同时出现在编辑器和编辑器中。董事会成员组,但不是管理员组的成员。

    首先,我使用Users,Groups和UserGroups表构建了我的数据库。 userGroups表包含以下字段:

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

    这种方法的问题在于,EF不会让我向这个表添加超过1个用户,因为它是1个User to Many关系,因此抛出了“违反多重约束”错误。

    所以我通过删除PK将其更改为多对多表:

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

    我现在能够访问user.Group并能够向该用户添加组。当我将用户添加到组时,我正在查询现有组并将其添加为:

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

    问题是,这在“组”表中为该用户创建了一个新组 - 即使该组的ID在保存到数据库时是正确的(12)。

    我需要做以下事情:

    1. 创建用户并将新用户分为1个或多个组。
    2. 编辑现有用户以在组中添加或删除它们。
    3. 我确信我做错了(可能是头脑发热),但如果有人能帮助我实现这一目标,我会非常感激。

      提前致谢!

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

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

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

      在我的项目中,群组实际上称为“角色”

      由于数据库中的UserGroups表是多对多的,因此它不会显示在EDMX文件中,而是显示在用户&组(我的数据库中的角色)链接为多对多。 Objects

      映射详情:

      User Mapping Details Roles Mapping Details

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题。我建议你做以下事情:

  1. 创建表UsersAndGroups(int:PK,UserId:FK,GroupId:FK)。
  2. 将Users和UsersAndGroups之间的关系建立为一对多。
  3. 将Groups和UsersAndGroups之间的关系建立为一对多。
  4. 删除用户和群组之间的关系。
  5. 这将允许您进行以下操作:

    1. 通过向UsersAndGroups表添加行来将用户添加到一个或多个组。
    2. 通过从UsersAndGroups表中选择具有特定UserId的所有记录来获取用户组。
    3. 通过从UsersAndGroups表中选择具有特定GroupId的所有记录来获取组用户。
    4. 希望我理解你。

答案 1 :(得分:0)

先使用代码:

为角色添加

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

给用户添加

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

您的课程可能如下所示

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

    }

}

迁移生成时,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);
相关问题