【问题标题】:Farther extending ApplicationUser class in ASP.NET MVC5 Identity system进一步扩展 ASP.NET MVC5 身份系统中的 ApplicationUser 类
【发布时间】:2014-01-30 12:40:11
【问题描述】:

我正在为大学创建一个简单的应用程序,学生可以在其中提出某种类型的请求,然后由特定专业的员工处理。

我想使用默认的 MVC5 身份系统并使用 TPH 模式扩展 ApplicationUser 类。所以我给ApplicationUser添加了通用属性:

public class ApplicationUser : IdentityUser
    {
        [Required]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        [Required]
        public string Email { get; set; }
    }

然后我创建了两个继承 ApplicationUser 的类:

public class Student : ApplicationUser
    {
        public string PersonalNumber { get; set; }
        public bool Monitor { get; set; }
        public virtual Group Group { get; set; }
        public virtual ICollection<Request> Requests { get; set; }
    }

public class Employee : ApplicationUser
    {
        public virtual EmployeeSpeciality EmployeeSpeciality { get; set; }
        public virtual ICollection<Request> Requests { get; set; }
    }

我目前想要的是让这两种类型的用户都注册为基本身份,并将两者都保存在一个表中,如 inheritance example on asp.net

正如我所想,在 AccountController 中初始化 user var 就足够了,然后将其作为 Student 或 Employee 传递给 UserManager。但是在尝试注册为学生后,我遇到了这个异常:

Exception Details: System.Data.SqlClient.SqlException: Invalid column name 'PersonalNumber'.
Invalid column name 'Monitor'.
Invalid column name 'EmployeeSpeciality_Id'.
Invalid column name 'Group_Id'.

我的上下文类:

public class EntityContext : IdentityDbContext
    {
        public EntityContext()
            : base("DbConnection")
        {
        }

        public DbSet<ApplicationUser> ApplicationUsers { get; set; }
        public DbSet<Student> Students { get; set; }
        public DbSet<Employee> Employees { get; set; }
        ...
    }

以及控制器操作的一部分:

public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new Student()
            {
                UserName = model.UserName,
                FirstName = model.FirstName,
                LastName = model.LastName,
                Email = model.Email
            };
            var result = await UserManager.CreateAsync(user, model.Password);

我尝试将 ApplicationClass 设置为抽象类,但没有成功。任何帮助将不胜感激。

更新:问题不在于代码本身。在对模型进行这些更改后,我根本没有删除(或更新)数据库。之后一切正常。

【问题讨论】:

    标签: entity-framework asp.net-mvc-5 asp.net-identity tph


    【解决方案1】:

    @Dragonheart:我试过这个 repro,如果你删除上下文类中的 DBSet 声明,它会正常工作。 IdentityDbContext 将处理您的 TPH 模式并在表中添加一个 Discriminator 列以区分子类。

    【讨论】:

    • 在您发表评论后,我试图重现一切(因为我已经通过将 Student 和 Employee 放在他们自己的表中并在 ApplicationUser 中为他们两个都拥有一个导航属性来转移到 TPT 模式)并且它即使不删除学生和员工的 DBSet 也可以工作。真正的问题有点傻——我只是忘记通过迁移删除或更新数据库。我知道,这是一个面罩。无论如何谢谢你的关注:)
    • @Dragonheart 如果这解决了您的问题,请将其作为答案发布并接受,以造福未来的读者。谢谢。
    【解决方案2】:

    由于ApplicationUser 继承自IdentityUser,因此将其从DbContext 类中删除。另一方面,不需要创建abstract 类(如果您阻止创建用户,除了StudentEmployee 类之外,您可以创建。有关更多信息,您可以查看Table-per-Hierarchy .

    对于Register 部分,尝试类似的操作:

    Student user = new Student
    {
        UserName = model.UserName,
        FirstName = model.FirstName,
        LastName = model.LastName,
        Email = model.Email
    };
    var result = UserManager.Create(user, model.Password);
    

    希望这会有所帮助...

    【讨论】:

    • 你为什么要创建一个新的ApplicationUser 实例,只是为了把它扔到下一行,用Student 实例替换它?
    • 我在同一个控制器上为两种类型的用户使用了这段代码,但在这种情况下,不需要创建 ApplicationUser 实例。出于这个原因,我想创建一个共享属性。感谢您告知...
    猜你喜欢
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2013-12-29
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多