我可以在ASP.NET MVC中创建多个身份表吗?

Com*_*555 2 asp.net-mvc-5 asp.net-identity

在我的项目中,Admin添加了教师,然后每个教师都会添加他的学生.添加后,他们会收到一封电子邮件,要求他们完成注册.

我的项目中有以下类:

1学生班

Student: int id, int Registry number, int grade, string password, string email, string name
Run Code Online (Sandbox Code Playgroud)

2-Instructor类:

Instructor: int id, string name , string email , string password
Run Code Online (Sandbox Code Playgroud)

3-My database context:

 public class InstructorContext:DbContext
{
    public InstructorContext() : base("InstructorContext")
    {
    }

    public DbSet<Instructor> Instructors { get; set; }
    public DbSet<Student> Students { get; set; }}
Run Code Online (Sandbox Code Playgroud)

当用户进入时,我必须确定他是管理员,讲师还是学生.我是否必须使用基于角色的身份验证?我已经有两个不同角色的单独课程.它们都可以从IdentityUser继承吗?

Chr*_*att 7

不,您不能拥有多个具有Identity的用户表,至少在技术上是这样.身份的所有其他核心组件(角色,声明,登录等)都使用外键设置到一个用户表.

对于您的场景,您应该使用继承.例如:

public class ApplicationUser : IdentityUser

public class Instructor : ApplicationUser

public class Student : ApplicationUser
Run Code Online (Sandbox Code Playgroud)

默认情况下,Entity Framework将为其创建一个表ApplicationUser并向其添加Discriminator列.此列将具有三个可能值之一:"ApplicationUser","Instructor"和"Student".当EF从该表中读取时,它将使用此列来实例化正确的类.这就是所谓的单表继承(STI),或者称为每层次表(TPH).这种方法的主要缺点是所有类的所有属性必须在同一个表上表示.如果您正在创建一个新Student的例子,那么a 的列Instructor仍将在记录中,只有这些值的空值或默认值.这也意味着您无法Instructor在数据库级别上强制执行属性,因为这会阻止保存ApplicationUser以及Student无法提供这些值的实例.换句话说,派生类中的所有属性都必须是可空的.但是,您始终可以使用视图模型强制执行类似于表单所需的属性.

如果你真的想拥有单独的表,你可以通过将继承策略更改为所谓的table-per-type(TPT)来实现这一目标.这将做的是保持表ApplicationUser,但添加两个额外的表,每个表为InstructorStudent.但是,所有核心属性,外键等都将在表中ApplicationUser,因为这是定义它们的地方.表Instructor和for表Student仅包含在这些类(如果有)上定义的属性以及表的外键ApplicationUser.查询时,EF将进行连接以从所有这些表中引入数据,并使用适当的数据实例化相应的类.像这样的一些纯粹主义者更好地保持数据在数据库中的标准化.但是,由于连接,它在查询方面必然更重.

最后一点需要注意的是,因为这会使人们不断地处理继承与身份.该UserManager班是一个通用类(UserManager<TUser>).AccountController例如,默认实例是.的实例UserManager<ApplicationUser>.因此,如果您使用该实例,则ApplicationUser无论Discriminator列的值如何,从查询返回的所有用户都将是实例.要获取Instructor实例,您需要实例化UserManager<Instructor>并将其用于Instructor相关的查询.

首次创建用户尤其如此.考虑以下:

var user = new Instructor();
UserManager.Create(user);
Run Code Online (Sandbox Code Playgroud)

您可能希望使用"Instructor"的鉴别器值保存用户,但实际上将使用"ApplicationUser"保存.这是因为,再次,UserManager是一个实例,UserManager<ApplicationUser>Instructor正在被提升.再说一次,只要你记得使用合适的类型,UserManager<TUser>你就没事了.