Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Farther extending ApplicationUser class in ASP.NET MVC5 Identity system

I'm creating a simple application for university where a student can make some type of request which is then processed by an employee of particular speciality.

I would like to use default MVC5 identity system and to extend the ApplicationUser class using TPH pattern. So I added the common properties to the ApplicationUser:

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

then I created two classes which inherits the 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; }
    }

what I currently want is to make both types of users register as a base Identity and to keep both in a single table as in the inheritance example on asp.net

As I thought, it would be enough to initialize user var in AccountController which is then passes to the UserManager as a Student or as an Employee. But after trying to register as a Student i'm getting this exception:

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

My context class:

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

and a part of controller's action:

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

I tried setting ApplicationClass to an abstract class, but no luck. Any help would be appreciated.

UPDATE: The problem wasn't in the code itself. I simply haven't dropped (or updated) the database after making these changes to the model. After it everything works just fine.

like image 978
Vladimir Glushkov Avatar asked Jan 11 '14 13:01

Vladimir Glushkov


1 Answers

@Dragonheart: I tried this repro and it would work fine if you remove the DBSet declarations in you context class. The IdentityDbContext would handle you TPH pattern and add a Discriminator column in the table to differentiate the child classes.

like image 72
Suhas Joshi Avatar answered Oct 30 '22 09:10

Suhas Joshi