Search code examples
entity-framework-coreasp.net-core-identityef-core-8.0

How to fix the error foreign key property 'ApplicationUserClaim.UserId1' was created in shadow state


I'm using

  • Microsoft.EntityFrameworkCore.SqlServer 8.0
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore 8.0

The overall problem I am trying to solve is that the following code will not work with Microsoft.AspNetCore.Identity out-of-the-box.

var usersClaims = await applicationDbContext.UserClaims.Include(uc=>uc.User).ToListAsync(); 

IdentityUserClaim does not have a baked-in property for User. IdentityUser does not have a baked-in property for ICollection<ApplicationUserClaim> Claims.

So I added the properties in my own classes and referenced the new classes in the declaration of ApplicationDbContext:

IdentityDbContext<ApplicationUser, ..., ApplicationUserClaim,...> 

See related code below:

public class ApplicationUser : IdentityUser<string>
{
    [Column(TypeName = "varchar(100)")]
    [MaxLength(100)]
    public string FirstName { get; set; } = string.Empty;

    [Column(TypeName = "varchar(100)")]
    [MaxLength(100)]
    public string LastName { get; set; } = string.Empty;
    public string FullName => $"{FirstName} {LastName}";

    [Required]
    public bool Enabled { get; set; } = true;

    public virtual ICollection<ApplicationUserClaim> Claims { get; set; } 
       = new List<ApplicationUserClaim>();
}
public class ApplicationUserClaim : IdentityUserClaim<string>
{
    [ForeignKey("User")]
    public override string UserId { get; set; } = null!;

    public virtual ApplicationUser User { get; set; } = null!;
}
ApplicationDbContext : IdentityDbContext<
        ApplicationUser,
        IdentityRole<string>,
        string,
        ApplicationUserClaim,
        IdentityUserRole<string>,
        IdentityUserLogin<string>,
        IdentityRoleClaim<string>,
        IdentityUserToken<string>>
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ...
    modelBuilder.Entity<ApplicationUserClaim>(entity =>
    {
         entity.HasOne(uc => uc.User)
               .WithMany(u => u.Claims)
               .HasForeignKey(uc => uc.UserId);
    });
    ...
}

When I add a migration, and update the database, EF Core creates duplicates the one-to-many relationships between AspNetUsers <1--∞> AspNetUserClaims. Why?

The error I need help with is:

Microsoft.EntityFrameworkCore.Model.Validation[10625] The foreign key property 'ApplicationUserClaim.UserId1' was created in shadow state because a conflicting property with the simple name 'UserId' exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type. See https://aka.ms/efcore-relationships for information on mapping relationships in EF Core.


Solution

  • I found the solution to my issue in the document: Identity model customization in ASP.NET Core

    The clue to finding the answer was buried in the error message "...or is incompatible with the associated primary key type.". I was able to solve the problem by changing my key types from string to GUID i.e.

    public class ApplicationUser : IdentityUser<Guid>{}
    
    public class ApplicationUserClaim : IdentityUserClaim<Guid>{}