.net core .NET核心2.1标识:为每个角色创建一个表;桥M:M表
对于在.NET Core 2.1项目中使用Identity的基于角色的授权,我在找出适合我需要的最佳设计时遇到了问题 我已经用ApplicationUser类从Identity扩展了User类。 我需要5个不同的角色来控制对应用程序不同功能的访问: 管理员、教师、学生、家长和主管 所有公共属性都保存在User和ApplicationUser中,但我仍然需要与其他表的不同关系,这取决于用户的角色.net core .NET核心2.1标识:为每个角色创建一个表;桥M:M表,.net-core,entity-framework-core,asp.net-core-identity,.net Core,Entity Framework Core,Asp.net Core Identity,对于在.NET Core 2.1项目中使用Identity的基于角色的授权,我在找出适合我需要的最佳设计时遇到了问题 我已经用ApplicationUser类从Identity扩展了User类。 我需要5个不同的角色来控制对应用程序不同功能的访问: 管理员、教师、学生、家长和主管 所有公共属性都保存在User和ApplicationUser中,但我仍然需要与其他表的不同关系,这取决于用户的角色 角色教师中的用户链接到1-N学校 学生角色中的用户链接到1-N组学生(但不直接链接到学校) 角色“家
- 角色教师中的用户链接到1-N学校
- 学生角色中的用户链接到1-N组学生(但不直接链接到学校)
- 角色“家长”中的用户链接到1-N学生(但不链接到学校)
public class ApplicationUser : IdentityUser
{
public string CustomTag { get; set; }
public string CustomTagBis { get; set; }
}
public class Teacher : ApplicationUser
{
public string TeacherIdentificationNumber { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Student : ApplicationUser
{
public ICollection<StudentGroup> Groups { get; set; }
}
public class Parent : ApplicationUser
{
public ICollection<Student> Children { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Title { get; set; }
public string Category { get; set; }
}
public class StudentGroup
{
public int Id { get; set; }
public string Name { get; set; }
}
导致产生此代码:
protected override void OnModelCreating(ModelBuilder builder)
{
//base.OnModelCreating(builder);
builder.Entity<Student>().ToTable("Student");
builder.Entity<Parent>().ToTable("Parent");
builder.Entity<Teacher>().ToTable("Teacher");
}
模型创建时受保护的覆盖无效(ModelBuilder)
{
//基于模型创建(生成器);
builder.Entity().ToTable(“学生”);
builder.Entity().ToTable(“父项”);
builder.Entity().ToTable(“教师”);
}
我相信这些标识键映射在base.OneModelCreating中。
但即使我取消注释该行,我也会在数据库中保留相同的结果
经过一些研究,我发现这有助于我完成创建每类型表模型的过程并应用迁移
使用这种方法,我有一个如下的模式:
表1每种类型的方法
如果我错了,请纠正我,但这两种技术都符合我的要求,而且更多的是关于设计的偏好?它对体系结构和身份特征都没有重大影响
对于第三种选择,我想用一种不同的方法,但我不太确定 这样的设计符合我的要求吗?它有效吗? 我的意思是,把一个教师实体链接到一个角色而不是一个用户,感觉很奇怪。但在某种程度上,教师实体代表了用户在担任教师角色时所需的功能 对实体的作用
我还不太确定如何用EF-core实现这一点,以及重写IdentityRole类将如何影响Identity特性。我正在研究,但还没有弄明白。你所做的完全符合你的要求。您当前实现的称为“每个层次的表”。这是实体框架在发现其模型时的默认方法 另一种方法是每种类型的
表格
。在这种情况下,实体框架将创建4个表
ApplicationUser
,因此数据库将在它们与父类之间生成FK关系
要实现这一点,您需要修改DbContext:
public class FooContext : DbContext
{
public DbSet<ApplicationUser> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().ToTable("Students");
modelBuilder.Entity<Parent>().ToTable("Parents");
modelBuilder.Entity<Teacher>().ToTable("Teachers");
}
}
公共类FooContext:DbContext
{
公共数据库集用户{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(“学生”);
modelBuilder.Entity().ToTable(“父项”);
modelBuilder.Entity().ToTable(“教师”);
}
}
这应该是最规范化的方法。然而,还有第三种方法,您将得到3个表,并且父ApplicationUser类将映射到其具体实现中。但是,我从未用Asp.Net Identity实现过这一点,因此我不知道它是否会工作,也不知道您是否会遇到一些关键冲突。我建议您利用Asp.Net core的新功能和新的Identity framework。关于这个问题有很多文档 您可以使用安全性,但在您的情况下,安全性似乎更合适 最好的方法是不要混合上下文。将关注点分开:身份上下文(使用UserManager)和业务上下文(学校、您的DbContext) 因为将ApplicationUser表放在“业务上下文”中意味着直接访问标识上下文。这不是使用标识的方式。使用UserManager进行与IdentityUser相关的查询 为了使其正常工作,请在学校上下文中创建用户表,而不是继承ApplicationUser表。它不是一个副本,而是一个新表。事实上,唯一的共同点是UserId字段 查看我的答案,了解关于更详细设计的想法 移动场
public class FooContext : DbContext
{
public DbSet<ApplicationUser> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().ToTable("Students");
modelBuilder.Entity<Parent>().ToTable("Parents");
modelBuilder.Entity<Teacher>().ToTable("Teachers");
}
}
new Claim("http://school1.myapp.com/TeacherIdentificationNumber", 123);
new Claim("http://school1.myapp.com/role", "Teacher");
new Claim("http://school2.myapp.com/role", "Student");