如何在 AspNetRoles 和 Menus 之间创建 ManyToMany 关系 table

How can I create ManyToMany relationship between AspNetRoles and Menus table

我正在使用 asp.net mvc 标识。我想在角色和菜单之间创建 ManyToMany 关系 table 我发现这可以在两个 table 之间的 EntityFramework 中创建 ManyToMany 关系 在 http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx

public class Role
{
    public Role() { }
    public int RoleId { get; set; }
    public string RoleName { get; set; }
    public virtual ICollection<Menu> Menus { get; set; }
}

public class Menu
{
    public Menu()
    {
        this.Roles = new HashSet<Role>();
    }
    public int MenuId { get; set; }
    public string MenuName { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

我找不到 AspNetRoles Class。我的问题是如何在现有身份 table 之间建立关系。多对多、一对多和多对一

经过一番搜索,我在这里找到了答案

我们只需要定义这个属性

public virtual IdentityRole IdentityRole { get; set; }

依赖于角色 class 这将解决问题。

之所以不删除这个post是为了涵盖这个答案问题的所有可能方面

我一直在尝试遵循您的解决方案,当然是基于您提出的问题。

我编辑了您 post 编写的第一个代码,以使其正常工作。我想解释身份表的使用以及扩展或自定义它们的一种正确方法。

注: 此代码在使用 ManyToOneOneToOne 关系

时有效
public virtual IdentityRole IdentityRole { get; set; }

但我不推荐它,因为在模型关系设计的某些点上,您会得到一些奇怪的和意想不到的结果。


现在我不得不说,这就是它对我有用的方式,我进行了很多测试并且总能得到我想要的。

诀窍很简单,始终扩展您的 IdentityModel,无论是哪一个...然后对扩展原始标识(关系、引用,添加属性等...)。

综上所述,让我们现在看看示例:

要获得您尝试获得的 ManyToMany 关系,您必须扩展 IdentityRole class,然后使用它进行定制。

我将重点关注 ManyToMany 关系示例,因为我觉得那里的示例不太常见。

我们开始吧:

两个示例的 DBContext 相同:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
      .
      .
      .

      override
      public IDbSet<IdentityRole> Roles { get; set; }
      public DbSet<Menu> Menus { get; set; }
    }

实体:

public class Role : IdentityRole
  {
    public Role() { }

    public string RoleName { get; set; }
    public virtual ICollection<Menu> Menus { get; set; }
  }

public class Menu
  {
    public Menu()
    {
      this.Roles = new HashSet<Role>();
    }

    public int Id{ get; set; }
    public string MenuName { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

生成此迁移的对象:

CreateTable(
    "dbo.Menus",
    c => new
        {
    Id = c.Int(nullable: false, identity: true),
    MenuName = c.String(),
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.AspNetRoles",
    c => new
        {
    Id = c.String(nullable: false, maxLength: 128),
    Name = c.String(nullable: false, maxLength: 256),
    RoleName = c.String(),
    Discriminator = c.String(nullable: false, maxLength: 128),
        })
    .PrimaryKey(t => t.Id)
    .Index(t => t.Name, unique: true, name: "RoleNameIndex");

CreateTable(
    "dbo.RoleMenus",
    c => new
        {
    Role_Id = c.String(nullable: false, maxLength: 128),
    Menu_Id = c.Int(nullable: false),
        })
    .PrimaryKey(t => new { t.Role_Id, t.Menu_Id })
    .ForeignKey("dbo.AspNetRoles", t => t.Role_Id, cascadeDelete: true)
    .ForeignKey("dbo.Menus", t => t.Menu_Id, cascadeDelete: true)
    .Index(t => t.Role_Id)
    .Index(t => t.Menu_Id);            

如您所见,有一个自动创建的枢轴 table RoleMenus 并自动添加了相应的关系。

另一方面,如果有人按照您的示例使用 IdentityRole 创建 ManyToMany 关系,使用 ICollection 。

让我们看看:

public class Role : IdentityRole
  {
    public Role() { }

    public string RoleName { get; set; }
    public virtual ICollection<Menu> Menus { get; set; }
  }

public class Menu
  {
    public Menu()
    {
      this.Roles = new HashSet<IdentityRole>();
    }

    public int Id{ get; set; }
    public string MenuName { get; set; }
    public virtual ICollection<IdentityRole> Roles { get; set; }
}

正在生成:

CreateTable(
    "dbo.Menus",
    c => new
        {
    Id = c.Int(nullable: false, identity: true),
    MenuName = c.String(),
    Role_Id = c.String(maxLength: 128),
        })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.AspNetRoles", t => t.Role_Id)
    .Index(t => t.Role_Id);

CreateTable(
    "dbo.AspNetRoles",
    c => new
        {
    Id = c.String(nullable: false, maxLength: 128),
    Name = c.String(nullable: false, maxLength: 256),
    RoleName = c.String(),
    Discriminator = c.String(nullable: false, maxLength: 128),
    Menu_Id = c.Int(),
        })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.Menus", t => t.Menu_Id)
    .Index(t => t.Name, unique: true, name: "RoleNameIndex")
    .Index(t => t.Menu_Id);

如您所见,创建的关系是 OneToOne 的尝试,而不是我们预期的结果,如果我们引用原始 IdentityModel 来建立某种关系,我们总会在某个时候出错。

所以我想就是这样,很抱歉这么长 post,但我觉得有人应该讨论如何编辑 IdentityModel 或者至少在一种功能方式。

所以我希望这能帮助 运行 将来有同样需要的人。

对不起我的英语。 问候。