0

I have an issue with custom users. I have a table called Profiles which I use for my users table (it wouldn't let me use Users, but that is a different issue!) and I created my dbcontext like this:

public partial class SkipstoneContext : IdentityDbContext<Profile>
{
    static SkipstoneContext()
    {
        Database.SetInitializer<SkipstoneContext>(null); // Existing data, do nothing
    }

    public SkipstoneContext()
        : base("DefaultConnection")
    {
    }

    // ...
    public DbSet<Company> Companies { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(model => model.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey<string>(model => model.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(model => new { model.RoleId, model.UserId });
        modelBuilder.Entity<UserSecret>().HasKey<string>(model => model.UserName);
    }
}

As you can see, I have no had to create a DbSet for Profile because that is set in the inherited IdentityDbContext class

My profile class looks like this:

public partial class Profile : IdentityUser
{
    public Profile()
    {
        // ...
    }

    public string CompanyId { get; set; }        
    public string Title { get; set; }
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
    // ...

    public virtual Company Company { get; set; }
    // ...
}

When I run my project I get an error stating

Invalid object name 'dbo.IdentityUsers'.

If I rename my table to IdentityUsers and run the project again I get an error stating

Invalid object name 'dbo.Profiles'.

And that is what is confusing. It looks like EF is looking for 2 tables for the Users and not just the one.

Can anyone explain to me why?

Update 1

So to try and figure this out, I removed the inherited IdentityDbContent from SkipstoneContext and just inherited from DbContext instead. The new context class looks like this:

public partial class SkipstoneContext : DbContext // : IdentityDbContext<Profile>
{
    static SkipstoneContext()
    {
        Database.SetInitializer<SkipstoneContext>(null); // Exsting database, do nothing
    }

    public SkipstoneContext()
        : base("DefaultConnection")
    {
    }

    // ...
    public DbSet<Company> Companies { get; set; }
    public DbSet<Profile> Profiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ...
        modelBuilder.Configurations.Add(new CompanyMap());
        modelBuilder.Configurations.Add(new ProfileMap());
        /// ...
        //modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(model => model.UserId);
        //modelBuilder.Entity<IdentityRole>().HasKey<string>(model => model.Id);
        //modelBuilder.Entity<IdentityUserRole>().HasKey(model => new { model.RoleId, model.UserId });
        //modelBuilder.Entity<UserSecret>().HasKey<string>(model => model.UserName);
    }
}

I also commented out my bindings for IdentityUserLogin, IdentityRole, IdentityUserRole and UserSecret and this is when it started working.

Here is a look at IdentityUserLogin:

public class IdentityUserLogin
{
    public IdentityUserLogin();

    public virtual string LoginProvider { get; set; }
    public virtual string ProviderKey { get; set; }
    public virtual IdentityUser User { get; set; }
    public virtual string UserId { get; set; }
}

It has a IdentityUser property and I think that is what is causing my issue. I know Profile inherits IdentityUser but for some reason it seems to think it is in another table.

So, my next task is to create a custom UserLogin and see if I can get EF to use that instread of IdentityUserLogin

2
  • Do you have a DbSet for Profile and IdentityUser? Commented Dec 9, 2013 at 15:15
  • no, that is what I am saying. IdentityDbContext should take care of my user table (I assume it would happily use Profiles as my User class is called Profile) but it seems to fall over for some reason Commented Dec 9, 2013 at 16:38

1 Answer 1

1

Ok, I figured this out. It was due to my mapping. I had my Profile mapping class which looked like this:

public class ProfileMap : EntityTypeConfiguration<Profile>
{
    public IdentityUserMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Properties
        this.Property(t => t.Id)
            .IsRequired()
            .HasMaxLength(128);

        this.Property(t => t.CompanyId)
            .IsRequired()
            .HasMaxLength(128);

        this.Property(t => t.CreatedById)
            .IsRequired()
            .HasMaxLength(128);

        this.Property(t => t.ModifiedById)
            .HasMaxLength(128);

        this.Property(t => t.Title)
            .IsRequired();

        this.Property(t => t.Forename)
            .IsRequired();

        this.Property(t => t.Surname)
            .IsRequired();

        this.Property(t => t.Email)
            .IsRequired();

        this.Property(t => t.CredentialId)
            .IsRequired();

        this.Property(t => t.PasswordHash)
            .HasMaxLength(128);

        this.Property(t => t.SecurityStamp)
            .HasMaxLength(128);

        this.Property(t => t.Discriminator)
            .HasMaxLength(128);

        // Table & Column Mappings
        this.ToTable("Profiles");
        this.Property(t => t.Id).HasColumnName("Id");
        this.Property(t => t.CompanyId).HasColumnName("CompanyId");
        this.Property(t => t.CreatedById).HasColumnName("CreatedById");
        this.Property(t => t.ModifiedById).HasColumnName("ModifiedById");
        this.Property(t => t.DateCreated).HasColumnName("DateCreated");
        this.Property(t => t.DateModified).HasColumnName("DateModified");
        this.Property(t => t.LastLoginDate).HasColumnName("LastLoginDate");
        this.Property(t => t.Title).HasColumnName("Title");
        this.Property(t => t.Forename).HasColumnName("Forename");
        this.Property(t => t.Surname).HasColumnName("Surname");
        this.Property(t => t.Email).HasColumnName("Email");
        this.Property(t => t.JobTitle).HasColumnName("JobTitle");
        this.Property(t => t.Telephone).HasColumnName("Telephone");
        this.Property(t => t.Mobile).HasColumnName("Mobile");
        this.Property(t => t.Photo).HasColumnName("Photo");
        this.Property(t => t.LinkedIn).HasColumnName("LinkedIn");
        this.Property(t => t.Twitter).HasColumnName("Twitter");
        this.Property(t => t.Facebook).HasColumnName("Facebook");
        this.Property(t => t.Google).HasColumnName("Google");
        this.Property(t => t.Bio).HasColumnName("Bio");
        this.Property(t => t.CompanyName).HasColumnName("CompanyName");
        this.Property(t => t.CredentialId).HasColumnName("CredentialId");
        this.Property(t => t.IsLockedOut).HasColumnName("IsLockedOut");
        this.Property(t => t.IsApproved).HasColumnName("IsApproved");
        this.Property(t => t.CanEditOwn).HasColumnName("CanEditOwn");
        this.Property(t => t.CanEdit).HasColumnName("CanEdit");
        this.Property(t => t.CanDownload).HasColumnName("CanDownload");
        this.Property(t => t.RequiresApproval).HasColumnName("RequiresApproval");
        this.Property(t => t.CanApprove).HasColumnName("CanApprove");
        this.Property(t => t.CanSync).HasColumnName("CanSync");
        this.Property(t => t.AgreedTerms).HasColumnName("AgreedTerms");
        this.Property(t => t.Deleted).HasColumnName("Deleted");
        this.Property(t => t.UserName).HasColumnName("UserName");
        this.Property(t => t.PasswordHash).HasColumnName("PasswordHash");
        this.Property(t => t.SecurityStamp).HasColumnName("SecurityStamp");
        this.Property(t => t.Discriminator).HasColumnName("Discriminator");

        // Relationships
    }
}

As you can see, the line that states

this.ToTable("Profiles");

that is the line that is causing the issue. Changing this solved my problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.