在我的项目中,管理员添加了教师,然后每个教师都添加了他的学生。添加后,他们会收到一封电子邮件,要求他们完成注册。
我的项目中有以下 class :
1-学生班
Student: int id, int Registry number, int grade, string password, string email, string name
2名教师:
Instructor: int id, string name , string email , string password
3-我的数据库上下文:
public class InstructorContext:DbContext
{
public InstructorContext() : base("InstructorContext")
{
}
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Student> Students { get; set; }}
用户登录时,我必须确定他是管理员还是讲师还是学生。我必须使用基于角色的身份验证吗?我已经有2个单独的类来担任不同的角色。它们是否都可以从IdentityUser继承?
最佳答案
不可以,至少在技术上不能有多个带有身份的用户表。身份的所有其他核心组件(角色,声明,登录名等)都使用指向一个用户表的外键进行设置。
对于这里的情况,您应该使用继承。例如:
public class ApplicationUser : IdentityUser
public class Instructor : ApplicationUser
public class Student : ApplicationUser
默认情况下,Entity Framework将为
ApplicationUser
创建一个表,并向其中添加Discriminator
列。该列将具有三个可能的值之一:“ApplicationUser”,“Instructor”和“Student”。当EF从该表中读取数据时,它将使用此列来实例化正确的类。这就是所谓的单表继承(STI)或按表层次结构(TPH)。这种方法的主要缺点是所有类的所有属性必须在同一张表上表示。例如,如果您要创建一个新的Student
,则Instructor
的列仍将保留在记录中,只有这些值的null或默认值。这也意味着您不能在数据库级别上对Instructor
之类的东西强制执行属性,因为那样会阻止保存无法提供这些值的ApplicationUser
和Student
实例。换句话说,派生类上的所有属性都必须为空。但是,您仍然可以始终使用 View 模型来强制执行诸如表单所需的属性之类的操作。如果您确实希望拥有单独的表,则可以通过将继承策略更改为所谓的每类型表(TPT)来在某种程度上实现该目标。这将使该表保留为
ApplicationUser
,但添加两个附加表,每个附加表分别为Instructor
和Student
。但是,所有核心属性,外键等都将在ApplicationUser
的表上,因为在那里定义了这些属性。 Instructor
和Student
的表将仅容纳在这些类(如果有)上定义的属性,以及ApplicationUser
的表的外键。查询时,EF将执行联接以从所有这些表中引入数据,并使用适当的数据实例化适当的类。一些纯粹主义者更喜欢这种方法,因为它将数据标准化在数据库中。但是,由于连接的原因,它在查询端必定会比较重。最后的警告是,这会使人们不停地处理与身份继承有关的问题。
UserManager
类是泛型类(UserManager<TUser>
)。例如,AccountController
中的默认实例是UserManager<ApplicationUser>
的实例。结果,如果您使用该实例,则无论ApplicationUser
列的值如何,从查询返回的所有用户都将是Discriminator
实例。要获取Instructor
实例,您需要实例化UserManager<Instructor>
并将其用于与Instructor
相关的查询。首次创建用户时尤其如此。考虑以下:
var user = new Instructor();
UserManager.Create(user);
您可能希望该用户使用“Instructor”的区分值保存,但实际上将使用“ApplicationUser”保存。这是因为
UserManager
再次是UserManager<ApplicationUser>
的一个实例,而您的Instructor
已被向上转换。同样,只要您记得使用适当类型的UserManager<TUser>
,就可以了。关于asp.net-mvc-5 - 我可以在ASP.NET MVC中创建多个身份表吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42163390/