-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicated foreign keys after restoring missing IdentityUser and IdentityRole navigation properties #9503
Comments
@bdominguez Are you saying that when you configure the navigations in the EF model (Labeled as "manual workaround" above) then there are still duplicated FKs? Or only if you add the navigation properties but don't explicitly configure them? |
I mean the second case. If I don't put that workaround code (explicit relationships) I get duplicated FKs because it seems that it doesn't resolve relationships correctly. |
This is an issue with the Identity documentation, as discussed in aspnet/Identity#1364. When adding navigations, the existing relationships in the model need to be configured to use the navigations, which requires the code above. If this is not done, then the naigations form a second set of relationships with a new FK. |
The above fix removed the extra foreighn keys, but when I added following navigation keys in the UserRole : IdentityUserRole model, it adds duplicate foreign keys in public class UserRole : IdentityUserRole<string>
{
public User User { get; set; }
public Role Role { get; set; }
}
|
@adnan-kamili the following parts of the original workaround are already configuring the relationships of builder.Entity<Role>()
.HasMany(e => e.Users)
.WithOne()
.HasForeignKey(e => e.RoleId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
...
builder.Entity<User>()
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade); You should be able to map the navigation properties you created by referencing them in the calls to It seems you are trying to configure the same relationships from the other side, but you are using the wrong cardinality (one-to-one as opposed to one-to-many). Since you are specifying two conflicting associations on each of the FKs, I assume EF Core let's the last one specified get the FK and resorts to creating an extra FK in shadow state for the original one. |
If I comment the code, as you said, It creates two additional foreign keys with names protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Role>()
.HasMany(e => e.Claims)
.WithOne()
.HasForeignKey(e => e.RoleId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
// modelBuilder.Entity<UserRole>().HasOne<User>(e => e.User)
// .WithOne().HasForeignKey<UserRole>(e => e.UserId);
// modelBuilder.Entity<UserRole>().HasOne<Role>(e => e.Role)
// .WithOne().HasForeignKey<UserRole>(e => e.RoleId);
modelBuilder.Entity<Role>(model =>
{
model.HasIndex(r => r.NormalizedName).HasName("RoleNameIndex").IsUnique(false);
model.HasIndex(r => new { r.NormalizedName, r.TenantId }).HasName("TenantRoleNameIndex").IsUnique();
});
} Additionally, If I don't set the reverse relationship, the |
@adnan-kamili what I suggested was actually not just to comment the code but to reference your new navigations in the The empty |
Thanks, it worked. So following is the final setting required: modelBuilder.Entity<Role>()
.HasMany(e => e.Claims)
.WithOne()
.HasForeignKey(e => e.RoleId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.HasMany(e => e.Roles)
.WithOne("User")
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Role>()
.HasMany(e => e.Users)
.WithOne("Role")
.HasForeignKey(e => e.RoleId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade); |
can someone explain specifically where to add these? I am at a loss here sorry I thought I could figure it out but I am stuck. |
@snibe See Add IdentityUser navigation properties here: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x |
@ajcvickers thanks! Guess I am dense today because i can't figure out where the following lines of code need to go. the rest seems clear to me Copy /// Navigation property for the roles this user belongs to. /// public virtual ICollection<IdentityUserRole> Roles { get; } = new List<IdentityUserRole>(); /// /// Navigation property for the claims this user possesses. /// public virtual ICollection<IdentityUserClaim> Claims { get; } = new List<IdentityUserClaim>(); /// /// Navigation property for this users login accounts. /// public virtual ICollection<IdentityUserLogin> Logins { get; } = new List<IdentityUserLogin>(); |
@snibe In ApplicationUser. |
ok i think i got it.. still stuck on this error though " 'ApplicationRole' does not contain a definition for 'Users' and no extension method 'Users' accepting a first argument of type 'ApplicationRole' could be found" |
sorry i am still at a loss with this stuff. I am now getting this error when trying to run in debug or add migrations. is there a better walk through of trying to do this? I am trying to convert this project >> https://code.msdn.microsoft.com/ASPNET-Core-MVC-Authenticat-ef5942f5 from 1.1 to 2.0 and i have followed >> https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x with adding the IdentityUser POCO section... I just can't seem to get passed this. |
Hi @ajcvickers I followed your instructions:
in apidbcontext.cs:
But each time I add-migration I have:
I m using:
Maybe your fix doesn t work anymore with the new version of Microsoft.EntityFrameworkCore.Tools? How can I add the list of Roles to User? |
I followed your instructions:
But as I said previously I have UserId1 created in AspNetUserRoles. Can you give more details about what you have done to fix the issue? Thanks |
Hi, Still not working. Is there someone who found a fix? |
Same issue here.
I keep getting this in my migration:
|
@MaverickMartyn @ranouf I have written the first draft of a document describing how to customize the Identity model--the PR is here: dotnet/AspNetCore.Docs#7288 I was not able to reproduce the issues you are seeing when following the steps from the document. |
This is correct like this |
I had the same problem with .net core 3.1, with the creation of duplicated Foreign Keys in the migration. |
Previously on 1.1.2 IdentityUser and IdentityRole provided the following navigation properties:
User
Role
Now if I manually add them (like it's written in 1.x to 2.0 migration docs) I get this when running migrations script:
Manual workaround:
Further technical details
EF Core version: 2.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Visual Studio 2017
The text was updated successfully, but these errors were encountered: