EF Core为用户添加角色并查询角色列表遇阻求助
Hey there, let's work through why your Users.Include(u => u.UserRoles).ToList() isn't loading the UserRoles as expected. I've seen a few common pitfalls with Identity navigation properties in EF Core 2.0, so let's break them down step by step:
1. Verify Your Entity Navigation Properties Are Correct
First, make sure your custom User class explicitly defines the UserRoles collection, and your UserRole (if custom) is set up properly:
// Your User class (should inherit IdentityUser) public class User : IdentityUser { // Add this navigation property if missing public virtual ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>(); } // If using a custom UserRole (instead of the default IdentityUserRole) public class UserRole : IdentityUserRole<string> { // Optional: Add additional properties here public virtual User User { get; set; } public virtual Role Role { get; set; } } // Your Role class (should inherit IdentityRole) public class Role : IdentityRole { // Optional: Add this if you need to navigate from Role to UserRoles public virtual ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>(); }
2. Ensure Your DbContext Configures the Relationship Properly
If you're using custom Identity entities, your DbContext must inherit from the generic IdentityDbContext with your custom types (adjust generic parameters if your key type isn't string). Then, override OnModelCreating to confirm the join table relationship:
public class AppDbContext : IdentityDbContext<User, Role, string, UserRole, IdentityUserClaim<string>, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Don't skip this! It sets up base Identity schema // Explicitly configure the UserRole join table (if needed) builder.Entity<UserRole>(ur => { ur.HasKey(ur => new { ur.UserId, ur.RoleId }); // Composite key is required for join tables ur.HasOne(ur => ur.User) .WithMany(u => u.UserRoles) .HasForeignKey(ur => ur.UserId) .IsRequired(); ur.HasOne(ur => ur.Role) .WithMany(r => r.UserRoles) .HasForeignKey(ur => ur.RoleId) .IsRequired(); }); } }
3. Check Startup.cs Identity Registration
Make sure you're registering Identity with your custom entities and the correct DbContext—don't mix default Identity types with your custom ones:
services.AddIdentity<User, Role>() .AddEntityFrameworkStores<AppDbContext>() // Use YOUR DbContext here .AddDefaultTokenProviders();
4. Rule Out Data & Query Execution Issues
- Check Database Data: Verify the
AspNetUserRolestable has entries linking your users to roles. If there's no data,Includewill return an empty collection (not null, if you initialized the collection like in step 1). - Avoid Lazy Loading Accidents: If you're trying to access
UserRoles.Rolewithout usingThenInclude, you might mistakenly thinkUserRolesisn't loaded—but it actually is, just not the nested Role. UseInclude(u => u.UserRoles).ThenInclude(ur => ur.Role)if you need the Role details too. - Confirm Query Execution: Ensure you're not accidentally working with an unexecuted
IQueryablebefore checkingUserRoles. Your use of.ToList()should execute the query immediately, but double-check in debug mode that the collection is populated after calling.ToList().
5. Ensure Package Version Consistency
In EF Core 2.0, mismatched versions between Microsoft.AspNetCore.Identity.EntityFrameworkCore, Microsoft.EntityFrameworkCore, and related packages can cause unexpected behavior. Make sure all your EF Core and Identity NuGet packages are on the same 2.0.x stable version.
If you've tried all these steps and still have issues, share a bit more about your entity definitions or any error messages you're seeing, and we can dig deeper!
内容的提问来源于stack exchange,提问作者Cedric Arnould

