Search code examples
c#entity-frameworkasp.net-identity

Why EF keep refusing "Include" on extended primary key in IdentityUserRole?


I extended my IdentityUser and IdentityUserToken. I am trying to output users and their roles. I keep getting this error

InvalidOperationException: The property 'RoleId' is not a navigation property of entity type 'IdentityUserRole'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.

    [HttpGet]
    public async Task<IActionResult> GetUsersList()
    {
      var users = await context.UserRoles
                        .Include(x=>x.RoleId)
                        .ToListAsync();

        return Ok(users);

    }

so I tried to add in my DbContext did not work either,

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

         modelBuilder.Entity<IdentityUserRole<string>>().HasKey(hk => new { hk.UserId, hk.RoleId});
          base.OnModelCreating(modelBuilder);
    }

why UserId or RoleId are not navigation properties, how can I use Include in this case?


Solution

  • in case someone struggles with extended Identity I am posting the answer down here, and the ref is here.

    1.Modify the ApplicationUser to add Roles Property

    // Add profile data for application users by adding properties to the ApplicationUser class
    public class ApplicationUser : IdentityUser
    {
        /// <summary>
        /// Navigation property for the roles this user belongs to.
        /// </summary>
        public virtual ICollection<IdentityUserRole<string>> Roles { get; } = new List<IdentityUserRole<string>>();
    
        // your rest properties
    }
    

    2. Modify ApplicationDbContext to add Role to User Entity

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
    
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        public DbSet<ApplicationUser> ApplicationUser { get; set; }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            // Customize the ASP.NET Identity model and override the defaults if needed.
            // For example, you can rename the ASP.NET Identity table names and more.
            // Add your customizations after calling base.OnModelCreating(builder);
            builder.Entity<ApplicationUser>()
                    .HasMany(e => e.Roles)
                    .WithOne()
                    .HasForeignKey(e => e.UserId)
                    .IsRequired()
                    .OnDelete(DeleteBehavior.Cascade);
        }
    }
    

    3. Build Project-> Package Manager Console-> Run add-migration addroletouser->Update-database

    1. Get Users with roles by code below:

      var users = await _context.ApplicationUser.Include(u => u.Roles).ToListAsync();