我试图遵循你的解决方案,当然基于你提出的问题。
我编辑了您发布的第一个代码以使其正常工作。我想解释身份表的使用以及扩展或自定义身份表的一种正确方法。
注意:
此代码在使用 ManyToOne 或 OneToOne 关系
时有效
public virtual IdentityRole IdentityRole { get; set; }
但我不建议这样做,因为在模型关系设计的某个时刻,您会得到一些奇怪且出乎意料的结果。
现在我不得不说,这就是它对我有用的方式,我测试了很多并且总是得到我想要的。
诀窍很简单,总是扩展你的 IdentityModel,不管是哪个......然后对这个扩展原始身份的模型做所有事情(关系、引用、添加属性等...)。
说了这么多,现在让我们看看示例:
要获得您尝试获得的 ManyToMany 关系,您必须扩展 IdentityRole 类,然后使用它进行自定义。
我将重点介绍 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);
如您所见,有一个自动创建的数据透视表RoleMenus并自动添加了各自的关系。
另一方面,如果有人效仿您的示例并使用 IdentityRole 使用 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 来建立某种关系,我们总是会在某些时候弄错了。
所以我想就是这样了,很抱歉这篇长文,但我觉得应该有人讨论如何编辑 IdentityModel 或至少以一种功能方式。
所以我希望这对将来遇到同样需要的人有所帮助。
对不起我的英语。
问候。