.NET Core 6 migration error: Cannot use table 'AspNetRoleClaims' for entity type 'IdentityRoleClaim<string>'

Viewed 587

After migrating a .NET Core 3.1 project to .NET Core 6, I receive the following error whenever my DbContext class is called:

InvalidOperationException: Cannot use table 'AspNetRoleClaims' for entity type 'IdentityRoleClaim' since it is being used for entity type 'AspNetRoleClaims' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'IdentityRoleClaim' on the primary key properties and pointing to the primary key on another entity type mapped to 'AspNetRoleClaims'.

After much searching, I have been unable to find a solution to this issue. The code I used in 3.1 worked fine, so I can only assume something has changed between then and now. Here is the code for my db context:

public partial class MyProjectContext : IdentityDbContext<IdentityUser>
{
    public MyProjectContext()
    {
    }

    public MyProjectContext(DbContextOptions<MyProjectContext> options)
        : base(options)
    {
    }

    public virtual DbSet<AspNetRoleClaims> AspNetRoleClaims { get; set; }
    public virtual DbSet<AspNetRoles> AspNetRoles { get; set; }
    public virtual DbSet<AspNetUserClaims> AspNetUserClaims { get; set; }
    public virtual DbSet<AspNetUserLogins> AspNetUserLogins { get; set; }
    public virtual DbSet<AspNetUserRoles> AspNetUserRoles { get; set; }
    public virtual DbSet<AspNetUserTokens> AspNetUserTokens { get; set; }
    public virtual DbSet<AspNetUsers> AspNetUsers { get; set; }

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

        modelBuilder.Entity<AspNetRoleClaims>(entity =>
        {
            entity.HasIndex(e => e.RoleId);

            entity.Property(e => e.RoleId).IsRequired();

            entity.HasOne(d => d.Role)
                .WithMany(p => p.AspNetRoleClaims)
                .HasForeignKey(d => d.RoleId);
        });

        modelBuilder.Entity<AspNetRoles>(entity =>
        {
            entity.HasIndex(e => e.NormalizedName, "RoleNameIndex")
                .IsUnique()
                .HasFilter("([NormalizedName] IS NOT NULL)");
        });

        modelBuilder.Entity<AspNetUserLogins>(entity =>
        {
            entity.HasKey(e => new { e.LoginProvider, e.ProviderKey });
        });

        modelBuilder.Entity<AspNetUserRoles>(entity =>
        {
            entity.HasKey(e => new { e.UserId, e.RoleId });
        });

        modelBuilder.Entity<AspNetUserTokens>(entity =>
        {
            entity.HasKey(e => new { e.UserId, e.LoginProvider, e.Name });
        });

        modelBuilder.Entity<AspNetUsers>(entity =>
        {
            entity.HasIndex(e => e.NormalizedUserName, "UserNameIndex")
                .IsUnique()
                .HasFilter("([NormalizedUserName] IS NOT NULL)");
        });
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("MyConnectionString"));
    }
}

I have following from the Microsoft documentation here

I have tried changing the class declaration to

public partial class IdentityDbContext : IdentityDbContext<IdentityUser, IdentityRole, string>

and received the same error.

I have also tried the following to address the foreign key issue

public partial class IdentityDbContext<TUser>
    : IdentityDbContext<TUser, IdentityRole, string>
        where TUser : IdentityUser

However, it results in a compiler error.

I have even tried stating the foreign key explicitly in the model declaration:

modelBuilder.Entity<AspNetRoleClaims>(entity =>
            {
                entity.HasIndex(e => e.RoleId);

                entity.Property(e => e.RoleId).IsRequired();

                entity.HasOne(d => d.Role)
                    .WithMany(p => p.AspNetRoleClaims)
                    .HasForeignKey(d => d.RoleId);

                //Tried to declare the relationship here
                entity.HasOne(d => d.RoleId)
                    .WithOne(p => p.*) //compiler error regardless of entry
                    .HasForeignKey(d => d.*) //compiler error regardless of entry
            });

Unsurprisingly, this didn't work either; I do not have any IdentityUser in my actual database.

So what am I missing here? I cannot find an easy way to troubleshoot this. It seems to trip the error the moment the Context class has finished processing, so that is where I suspect the problem may lie.

Any thoughts on how to fix this?

Edit: Here is the IdentityUser class. It is the default included with the framework.

namespace Microsoft.AspNetCore.Identity
{
    //
    // Summary:
    //     The default implementation of Microsoft.AspNetCore.Identity.IdentityUser`1 which
    //     uses a string as a primary key.
    public class IdentityUser : IdentityUser<string>
    {
        //
        // Summary:
        //     Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityUser.
        //
        // Remarks:
        //     The Id property is initialized to form a new GUID string value.
        public IdentityUser()
        {
            Id = Guid.NewGuid().ToString();
            SecurityStamp = Guid.NewGuid().ToString();
        }

        //
        // Summary:
        //     Initializes a new instance of Microsoft.AspNetCore.Identity.IdentityUser.
        //
        // Parameters:
        //   userName:
        //     The user name.
        //
        // Remarks:
        //     The Id property is initialized to form a new GUID string value.
        public IdentityUser(string userName)
            : this()
        {
            UserName = userName;
        }
    }
}
1 Answers
Related