2017-02-10 63 views
1

在我的项目中,Admin添加了教师,然后每个教师添加他的学生。当他们被添加时,他们会收到一封电子邮件,要求他们完成注册。我可以在ASP.NET MVC中创建多个身份表吗?

我在我的项目中的以下类:

1-Student类

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继承?

回答

2

不,你不能有多个用户表与身份,至少不是在技术上。 Identity(角色,声明,登录等)的所有其他核心组件都使用外键设置为一个用户表。

对于你的场景,你应该使用继承。例如:

public class ApplicationUser : IdentityUser 

public class Instructor : ApplicationUser 

public class Student : ApplicationUser 

默认情况下,实体框架将创建一个表ApplicationUserDiscriminator列添加到它。此列将具有三个可能值之一:“ApplicationUser”,“教师”和“学生”。当EF从该表中读取时,它将使用该列来实例化正确的类。这就是所谓的单表继承(STI)或者作为每级表(TPH)。这种方法的主要缺点是所有类的所有属性都必须在同一个表中表示。例如,如果要创建新的Student,则Instructor的列仍将保留在记录中,只有这些值为空值或默认值。这也意味着您无法在数据库级别强制执行类似Instructor之类的属性,因为这会阻止保存无法提供这些值的ApplicationUserStudent实例。换句话说,派生类的所有属性都必须为空。但是,您始终可以使用视图模型来强制执行类似于表单目的所需的属性。

如果你真的想要分开的表,你可以通过改变继承策略到所谓的按类型(TPT)来实现这个目标。这将做的是保持表ApplicationUser,但添加两个额外的表,InstructorStudent各一个。然而,所有的核心属性,外键等将在ApplicationUser的表格中,因为那是定义它们的地方。 InstructorStudent的表格将仅容纳在这些类别(如果有的话)上定义的属性以及ApplicationUser的表格的外键。查询时,EF将会进行连接以从所有这些表中获取数据并使用适当的数据实例化适当的类。像这样的一些纯粹主义者更好地保持数据库中的数据标准化。但是,由于连接的原因,在查询方面它必然更重。

最后一句要谨慎,因为这会让人们不断地处理与身份的继承关系。UserManager类是一个通用类(UserManager<TUser>)。例如,AccountController中的默认实例是UserManager<ApplicationUser>的实例。因此,如果使用该实例,则查询返回的所有用户将为ApplicationUser实例,而不管Discriminator列的值如何。要获取Instructor实例,您需要实例化UserManager<Instructor>并将其用于与Instructor相关的查询。

第一次创建用户尤其如此。考虑以下几点:

var user = new Instructor(); 
UserManager.Create(user); 

您可能认为用户将与“导师”的鉴别值被保存,但它实际上与“ApplicationUser”保存。这是因为UserManager又是UserManager<ApplicationUser>的一个实例,并且您的Instructor正在上传。再一次,只要你记得使用适当类型的UserManager<TUser>,你会没事的。

+0

如果我只有1个管理员,我必须添加“管理员”类吗?还是足以检查电子邮件和密码? – Comp23555

+0

不,我的意思是你*可以*,但“管理员”更通常被认为是一个角色。区分的一个好方法是考虑重叠。如果像“讲师”这样的东西也可能是管理员(不管你是否真的会允许),那么它可能更适合作为一个角色。这样,如果您需要,您*可以*使教师成为管理员,而不会影响系统的其他部分。否则,你最终会得到类似'Instructor','Admin'和'AdminInstructor'这样的东西,这显然很快就会变得混乱, –

+0

另外,通过使用角色,你可以添加类似'[Authorize(Roles =“Admin “)]'给控制器/仅限管理员的操作。作为另一种派生类型,您需要创建一些自定义来确定访问级别。 –

相关问题