EF三方多对多关联(User/Account/Permission)实体与模型创建求助
EF Core 实体关系配置方案(基于User聚合根设计)
1. 定义实体类
User 实体
public class User { public int Id { get; set; } public string Name { get; set; } // 关联用户的账户关联记录集合 public ICollection<UserAccount> UserAccounts { get; set; } = new List<UserAccount>(); }
Account 实体
public class Account { public int Id { get; set; } public string AccountName { get; set; } // 关联账户对应的用户关联记录集合 public ICollection<UserAccount> UserAccounts { get; set; } = new List<UserAccount>(); }
Permission 实体
public class Permission { public int Id { get; set; } public string PermissionName { get; set; } // 关联权限对应的用户账户权限记录集合 public ICollection<UserAccountPermission> UserAccountPermissions { get; set; } = new List<UserAccountPermission>(); }
UserAccount 实体(显式连接表,需关联Permission)
public class UserAccount { public int UserId { get; set; } public User User { get; set; } public int AccountId { get; set; } public Account Account { get; set; } // 关联该用户账户的权限集合 public ICollection<UserAccountPermission> UserAccountPermissions { get; set; } = new List<UserAccountPermission>(); }
UserAccountPermission 实体(显式连接表)
public class UserAccountPermission { public int UserAccountUserId { get; set; } public int UserAccountAccountId { get; set; } public UserAccount UserAccount { get; set; } public int PermissionId { get; set; } public Permission Permission { get; set; } }
2. DbContext 配置
public class AppDbContext : DbContext { public DbSet<User> Users { get; set; } public DbSet<Account> Accounts { get; set; } public DbSet<Permission> Permissions { get; set; } public DbSet<UserAccount> UserAccounts { get; set; } public DbSet<UserAccountPermission> UserAccountPermissions { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 替换为你的数据库连接字符串 optionsBuilder.UseSqlServer("YourConnectionStringHere"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置UserAccount的复合主键 modelBuilder.Entity<UserAccount>() .HasKey(ua => new { ua.UserId, ua.AccountId }); // 配置User与UserAccount的一对多关系 modelBuilder.Entity<UserAccount>() .HasOne(ua => ua.User) .WithMany(u => u.UserAccounts) .HasForeignKey(ua => ua.UserId); // 配置Account与UserAccount的一对多关系 modelBuilder.Entity<UserAccount>() .HasOne(ua => ua.Account) .WithMany(a => a.UserAccounts) .HasForeignKey(ua => ua.AccountId); // 配置UserAccountPermission的复合主键 modelBuilder.Entity<UserAccountPermission>() .HasKey(uap => new { uap.UserAccountUserId, uap.UserAccountAccountId, uap.PermissionId }); // 配置UserAccount与UserAccountPermission的一对多关系 modelBuilder.Entity<UserAccountPermission>() .HasOne(uap => uap.UserAccount) .WithMany(ua => ua.UserAccountPermissions) .HasForeignKey(uap => new { uap.UserAccountUserId, uap.UserAccountAccountId }); // 配置Permission与UserAccountPermission的一对多关系 modelBuilder.Entity<UserAccountPermission>() .HasOne(uap => uap.Permission) .WithMany(p => p.UserAccountPermissions) .HasForeignKey(uap => uap.PermissionId); } }
3. 基于User聚合根的查询示例
查询用户及其所有账户,以及每个账户的权限
using (var context = new AppDbContext()) { var userWithAccountsAndPermissions = context.Users .Include(u => u.UserAccounts) .ThenInclude(ua => ua.Account) .Include(u => u.UserAccounts) .ThenInclude(ua => ua.UserAccountPermissions) .ThenInclude(uap => uap.Permission) .FirstOrDefault(u => u.Id == 1); // 替换为目标用户ID }
关键说明
- 必须显式创建
UserAccount实体,因为它还要和Permission建立关联——EF自动生成的隐式多对多连接表只能单纯绑定两个实体,没法再附加其他关系。 UserAccountPermission也得显式定义,因为它关联的UserAccount是复合主键实体,EF无法自动处理这种复杂的多对多关联。- 这套设计完全贴合你以
User为聚合根的需求:所有数据查询都从User切入,先拿到用户的账户,再通过账户对应的UserAccount获取权限。
内容的提问来源于stack exchange,提问作者Pedro Costa
相关产品推荐
相关产品推荐

