EF Core 聚合根间无导航集合的多对多关系Fluent API配置问题
回答
完全可以实现,EF Core 5及以上版本原生支持无导航属性的多对多关联配置,完全适配你遵循DDD聚合原则、仅通过ID关联的设计要求,最终可以生成仅包含UserId、CompanyId两列的关联表。
配置示例
领域实体(符合聚合根设计,无实体类型引用)
public class Company { public int Id { get; set; } // 仅存储关联用户ID,不引用User实体类型 public List<int> UserIds { get; set; } = new(); } // 建议将原类名Users调整为符合命名规范的User public class User { public int Id { get; set; } // 仅存储关联公司ID,不引用Company实体类型 public List<int> CompanyIds { get; set; } = new(); }
Fluent API 配置代码
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置多对多关联表 modelBuilder.Entity<Company>() .HasMany<User>() .WithMany() .UsingEntity( "CompanyUserRelations", // 可自定义关联表名称 l => l.HasOne<User>().WithMany().HasForeignKey("UserId").IsRequired(), r => r.HasOne<Company>().WithMany().HasForeignKey("CompanyId").IsRequired(), j => j.HasKey("UserId", "CompanyId") // 配置联合主键 ); // 可选配置:如果需要将ID集合持久化到聚合根自身的表字段中 // 以下配置用JSON格式存储ID列表,也可以根据需要改成逗号分隔等其他格式 modelBuilder.Entity<Company>() .Property(c => c.UserIds) .HasConversion( ids => System.Text.Json.JsonSerializer.Serialize(ids, (JsonSerializerOptions)null), json => System.Text.Json.JsonSerializer.Deserialize<List<int>>(json, (JsonSerializerOptions)null) ?? new() ) .Metadata.SetValueComparer(new ValueComparer<List<int>>( (c1, c2) => c1.SequenceEqual(c2), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => c.ToList() )); // 同理配置User的CompanyIds属性 modelBuilder.Entity<User>() .Property(u => u.CompanyIds) .HasConversion( ids => System.Text.Json.JsonSerializer.Serialize(ids, (JsonSerializerOptions)null), json => System.Text.Json.JsonSerializer.Deserialize<List<int>>(json, (JsonSerializerOptions)null) ?? new() ) .Metadata.SetValueComparer(new ValueComparer<List<int>>( (c1, c2) => c1.SequenceEqual(c2), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => c.ToList() )); }
注意事项
- 该配置依赖EF Core 5及以上版本,更低版本需要手动定义关联实体类来实现相同效果
- 如果你不需要在聚合根表中额外存储ID集合,可以直接删除实体中的
UserIds、CompanyIds属性以及对应的转换配置,关联表仍然可以正常生成使用 - 关联表的操作可以直接通过EF Core的
DbContextAPI完成,不需要修改领域实体的设计
内容的提问来源于stack exchange,提问作者David Masters
相关产品推荐
相关产品推荐

