Thiago M
Thiago M

Reputation: 191

Extra column/field on IdentityUserRoles table using Identity 2 and Entity Framework 6

I'm using a custom implementation of the IdentityUser class in my project.
The problem is that Entity Framework adds an extra column in the table IdentityUserRoles, mapping the child class Id as a constraint.
I know that EF is probably getting confused on figuring how to map the relationship with this new class, I just don't know why and how to solve it. I've been searching the web about this EF behavior, but couldn't find a solution yet.

Here are some screenshots that summarize the problem:

UsuarioClass DefaultContext DefaultCotextModelCreating UsuarioFuncaoScheme UsuarioMap

Upvotes: 3

Views: 2067

Answers (3)

I've found the same issue. There is a much simpler solution. You should explicitly define the relation on the IdentityUserRole configuration.

E.g.:

public class UserRoleConfiguration : EntityTypeConfiguration<UserRole>
{
    public UserRoleConfiguration()
    {
        HasKey(x => new {x.UserId, x.RoleId});
        HasRequired(x => x.User).WithMany(x => x.Roles).WillCascadeOnDelete();
    }
}

Upvotes: 0

Thiago M
Thiago M

Reputation: 191

So, I've rechecked my database mappings, and I think I have found a solution for this problem:

My user class mapping was located in another file (UsuarioMap), that inherited from EntityTypeConfiguration, and then I would specify my configurations in its constructor, exactly like the image in the post. (IMHO this is better for code organization). Now my IdentityUser (Usuario) table configuration it's simply located inside the OnModelCreating method:

        modelBuilder.Entity<Usuario>().ToTable("Usuario");
        modelBuilder.Entity<Usuario>().Property(u => u.UserName).IsRequired();
        modelBuilder.Entity<Usuario>().Property(u => u.Email).IsRequired();
        modelBuilder.Entity<Usuario>().Property(u => u.PasswordHash).IsRequired();
        modelBuilder.Entity<Usuario>().Property(u => u.Nome).IsRequired();
        modelBuilder.Entity<Usuario>().Property(u => u.DataRegistro).IsRequired();
        modelBuilder.Entity<Usuario>().Property(u => u.UltimoLogin).IsOptional();
        modelBuilder.Entity<Usuario>().HasOptional(u => u.Cliente).WithMany(c => c.Usuarios);

I honestly don't know why Entity Framework look at this two configurations paths differently since the parameter of modelBuilder.Configurations.Add() and the return of modelBuilder.Entity() is a System.Data.Entity.ModelConfiguration.EntityTypeConfiguration object, so logically both ways should work.

Upvotes: 2

tlyng
tlyng

Reputation: 87

Cannot supply a full technical explanation but I made these changes in my code to overcome the problem:

public class ResultzContext : IdentityDbContext<ApplicationUser>
    {
        public ResultzContext()
            : base("ResultzConnection")
        {

        }


        static ResultzContext()
        {
            // Set the database intializer which is run once during application start
            // This seeds the database with admin user credentials and admin role
            Database.SetInitializer<ResultzContext>(new ApplicationDbInitializer());
        }

        public static ResultzContext Create()
        {
            return new ResultzContext();
        }

: :

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
                base.OnModelCreating(modelBuilder);
                //modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id).ToTable("AspNetRoles");
//modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
                modelBuilder.Entity<ApplicationUser>().ToTable("AspNetUsers");
                //modelBuilder.Entity<IdentityUserLogin>().HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey }).ToTable("AspNetUserLogins");
                //modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId }).ToTable("AspNetUserRoles");
                //modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");

So, generally commented out everything and changed from IdentityUser to ApplicationUser. But need to add that I originally had code for Identity 1.0 Hope it can help you!

Upvotes: 0

Related Questions