我可以在ASP.NET MVC中创建多个标识表吗



在我的项目中,管理员添加讲师,然后每个讲师添加他的学生。添加后,他们将收到一封电子邮件,要求他们完成注册。

我的项目中有以下课程:

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; }}

当用户登录时,我必须确定他是管理员、讲师还是学生。我必须使用基于角色的身份验证吗?我已经为不同的角色提供了两个单独的类。它们是否都可以从IdentityUser继承?

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

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

public class ApplicationUser : IdentityUser
public class Instructor : ApplicationUser
public class Student : ApplicationUser

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

如果真的想要有单独的表,那么可以通过将继承策略更改为所谓的每类型表(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);

您可能期望用户保存时使用鉴别器值"Coacher",但实际保存时使用"ApplicationUser"。这是因为,UserManagerUserManager<ApplicationUser>的一个实例,而您的Instructor正在被上广播。同样,只要你记得使用合适类型的UserManager<TUser>,你就可以了。

相关内容

  • 没有找到相关文章

最新更新