question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The derived type 'UserRole' cannot have KeyAttribute on property 'Id' since primary key can only be declared on the root type

See original GitHub issue

Hi everyone!

Steps to reproduce

  • Create ASP.NET Core application from yo generator-aspnetcore-spa with ‘Angular 2’ template (for example, with name ‘Web.Client.Spa’).
  • Create .NET Core class library project (for example, with name ‘Core.DAL.Real.Database’) for EF DbContext (and create in this project EF DbContext).
  • Create .NET Core class library project for domain models (for example, ‘Core.DomainModels’ and ‘Core.DomainModels.Identity’ - first project for domain models classes and second project for the ASP.NET Identity models [for EF CodeFirst approach]).

In project ‘Core.DomainModels’ add this file: IEntity.cs:

    public interface IEntity<T>
    {
        T Id { get; set; }
    }

    public interface IEntity : IEntity<Guid>
    {

    }

And in project ‘Core.DomainModels.Identity’ add this classes:

Abstract & interfaces: IUser.cs

    public interface IUser<T> : IEntity<T>
    {
        DateTime RegisterDate { get; set; }
    }

    public interface IUser : IUser<Guid>
    {

    }

IRole.cs

    public interface IRole<T> : IEntity<T>
    {
        string Name { get; set; }
    }

    public interface IRole : IRole<Guid>
    {

    }

IUserRole.cs

    public interface IUserRole<T>// : IEntity<T>
    {
        T UserId { get; set; }
        T RoleId { get; set; }

        IUser User { get; set; }
        IRole Role { get; set; }
    }

    public interface IUserRole : IUserRole<Guid>
    {

    }

Real models: User.cs

    public class User : IdentityUser<Guid>, IUser<Guid>
    {
        public static User CreateEmptyInstance()
        {
            return new User();
        }

        #region Implementation of IUser<Guid>

        public DateTime RegisterDate { get; set; }

        #endregion

        [NotMapped]
        public bool IsAuthenticated { get; set; }

    }

Role.cs

    public class Role : IdentityRole<Guid>, IRole<Guid>
    {

    }

UserRole.cs

    public class UserRole : IdentityUserRole<Guid>, IUserRole
    {

        #region Implementation of IEntity<Guid>

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public Guid Id { get; set; }

        #endregion
        #region Implementation of IUserRole<Guid>

        [NotMapped]
        public IUser User { get; set; }

        [NotMapped]
        public IRole Role { get; set; }

        #endregion
    }
  • Add packages ASP.NET Identity, EF Core (with Tools and Design), Npgsql to MVC App (I’m used PostgreSQL database).
  • Add packages EF Core (with Tools) to Core.DAL.Real.Database project.
  • In Package Manager Console run command (for startup project Core.DAL.Real.Database):
Add-Migration InitDev -Context EfDbMigrations -Environment Development
  • …And I have an error:
System.InvalidOperationException: The derived type 'UserRole' cannot have KeyAttribute on property 'Id' since primary key can only be declared on the root type.    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.KeyAttributeConvention.Apply(InternalModelBuilder modelBuilder)
    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder) 
    at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) 
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() 
    at Microsoft.EntityFrameworkCore.Internal.LazyRef`1.get_Value() 
    at Microsoft.Extensions.DependencyInjection.ServiceProvider.ScopedCallSite.Invoke(ServiceProvider provider) 
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) 
    at Microsoft.Extensions.DependencyInjection.ServiceProvider.TransientCallSite.Invoke(ServiceProvider provider) 
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite.Invoke(ServiceProvider provider) 
    at Microsoft.Extensions.DependencyInjection.ServiceProvider.TransientCallSite.Invoke(ServiceProvider provider) 
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) 
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) 
    at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) 
    at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.Execute(CommonOptions commonOptions, String name, String outputDir, String context, String environment, Action`1 reporter) 
    at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.<>c__DisplayClass0_0.<Configure>b__0() 
    at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args) 
    at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
 The derived type 'UserRole' cannot have KeyAttribute on property 'Id' since primary key can only be declared on the root type. 

My project.json in Core.DAL.Real.Database project:

{
  "version": "1.0.0-*",

  "dependencies": {
    "NETStandard.Library": "1.6.0",
    "Microsoft.EntityFrameworkCore": "1.0.1",
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview2-final",
      "type": "build"
    },
    "Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.1",
    "System.Linq": "4.1.0",
    "Core.DomainModels.Identity": "1.0.0-*",
    "Core.DomainModels": "1.0.0-*"
  },

  "frameworks": {
    "netcoreapp1.0": {      
      "imports": "dnxcore50"
    }
  },

  "tools": {
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
  } 
}

The issue

The KeyAttribute on property Id in my UserRole class must not throw this error, right? Or I do something wrong?

I found the same issue #5898 but that issue is closed by @AndriySvyryd and appropriate changes (by commit https://github.com/aspnet/EntityFramework/commit/5ce5b86d37859a1410d9e343489f8b2d3fbb9527) are included in 1.0.1 version of EF Core which I used. I’m confused because of this error. And because of this, I cannot create my first (init) migration…

Please help solve this problem…

Further technical details

EF Core version: 1.0.1 Operating system: Windows 10 Visual Studio version: VS 2015 Update 3

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
AndriySvyrydcommented, Dec 10, 2020

@Cubelaster Something like this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ConfigureBase(modelBuilder.Entity<MyDerived>());
}

protected EntityTypeBuilder<T> ConfigureBase<T>(EntityTypeBuilder<T> entityType)
    where T : MyBase
{
    ConfigureTranslations(entityType.Property(d => d.MyTranslations));
    return entityType;
}

protected PropertyBuilder<Translations> ConfigureTranslations(PropertyBuilder<Translations> property)
    => property.HasConversion(
        v => JsonConvert.SerializeObject(v),
        v => JsonConvert.DeserializeObject<Translations>(v))
        .HasColumnType("json");
private class MyBase
{
    public string Id { get; set; }
    public Translations MyTranslations { get; set; }
}

private class MyDerived : MyBase
{
}

private class Translations
{
}
1reaction
AndriySvyrydcommented, Dec 8, 2020

@Cubelaster Avoid using the base type in OnModelCreating if you don’t want it included in the model.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to not declare key in root model in EntityFramework core
The derived type cannot have KeyAttribute on property 'Id' since the primary key can only be declared on the root type.
Read more >
CoreStrings.KeyAttributeOnDerivedEntity Method
The derived type '{derivedType}' cannot have the [Key] attribute on property '{property}' since primary keys may only be declared on the root type....
Read more >
Data Annotations: Key Attribute in EF 6 & EF Core
The Key attribute can be applied to a property in an entity class to make it a key property and the corresponding column...
Read more >
4 Creating a Business Domain Layer Using Entity Objects
This chapter describes how to use ADF entity objects to create a reusable business layer of Java objects that describe the business domain...
Read more >
How to Define Keyless Entities in .NET EF Core
When an entity is defined as keyless entity, it cannot contain a primary key. So it can never be a principal entity as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found