50

I have created a class in MVC5, where I want a primary owner of the content and then I want to have some editors for the content:

public class Content
{
    public int ID { get; set; }
    public IdentityUser Owner { get; set; }
    public ICollection<IdentityUser> Editors { get; set; }
    public string Title{ get; set; }
    public string Body { get; set; }
}

In the database context I have the following code:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Content>()
        .HasOptional(c => c.Editors)
        .WithRequired()
        .WillCascadeOnDelete();

    modelBuilder.Entity<Content>()
        .HasRequired(c => c.Owner)
        .WithOptional()
        .WillCascadeOnDelete();
}

I would expect Microsoft to have implemented the IdentityUser object in such a way, that it can be used in other entity types, so I am probably doing something wrong, because when I try to make a controller for the Content entity type, I get the following error:

EntityType 'IdentityUserLogin' has no key defined
EntityType 'IdentityUserRole' has no key defined
EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no key defined
EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no key defined

I have also tried to add the following code to the ApplicationDbContext as described in this question Map tables using fluent api in asp.net MVC5 EF6?:

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

I must be doing something wrong. Please tell me how I can handle users in my Content EntityType.

Community
  • 1
  • 1
Gunnar
  • 986
  • 3
  • 10
  • 24
  • Your `Content` class appears to be missing the foreign key ID. – Sam Axe Nov 11 '13 at 21:13
  • When working with EntityFramework, you don't need a foreign key ID field. You just set a property to the associated type and EF does the rest (like storing a foreign key ID in the database). – Finster Feb 25 '14 at 19:55

2 Answers2

106

I had the same problem and I found that I had not called

 base.OnModelCreating(modelBuilder);

in my DbModel

Aaron
  • 1,497
  • 1
  • 12
  • 3
  • 25
    This shoudl be the accepted the answer, a lot of people remove the base class implementation with DbContext but it is vital when inheriting from IdentityDbContext – Oliver Nov 18 '14 at 11:29
  • 2
    I got the same error and before using the accepted answer, I read your answer and realized I had removed that line of code. That solved the problem and am sure this is the answer most of the time someone runs into this issue. – Dev Jul 10 '15 at 15:46
62

The following method, OnModelCreating, will create a working context. Not sure if it is the mapping you want though.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Content>()
        .HasMany(c => c.Editors)
        .WithOptional()
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<Content>()
        .HasRequired(c => c.Owner)
        .WithOptional()
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
    modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
    modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Olav Nybø
  • 11,454
  • 8
  • 42
  • 34
  • 2
    My mistake, I have two contexts, application context and content context, and I had my key mappings for the IdentityUser in the application context. Now it works like a charm. Thanks. – Gunnar Nov 12 '13 at 17:22
  • 1
    Is it a bug? i have another context and no relate to ASP.NET Identity context that project created. so why i have a the last 3 lines? – Cheung Mar 17 '14 at 07:40
  • Error to generate model entity:Se han detectado uno o varios errores de validación durante la generación del modelo: Usuario_ObPais_Source: : La multiplicidad no es válida en el rol (Role) 'Usuario_ObPais_Source' de la relación 'Usuario_ObPais'. Como las propiedades de Dependent Role no son las propiedades de clave, el límite superior de la multiplicidad de Dependent Role debe ser '*'. – e-info128 Aug 31 '14 at 17:01
  • 1
    This worked fine until you go into details. The PROBLEM with this approach is, that if you want to add multiple user logins for the same user(facebook & google), this will not work because the primary key is set to the UserId in IdentityUserLogin. You cannot add multiple external logins with the same primary key. – Pinte Dani Oct 05 '15 at 10:36