EF Core中父表与多子表基于DrugId的关联配置问题
EF Core 关联配置与导航查询方案
首先修正实体类,移除冗余的重复外键列,添加对应导航属性:
实体类调整
父表 BasicData
public class BasicData { public int DrugId { get; set; } // 复用该列作为所有子表的外键 public int FormCode { get; set; } // 导航属性:关联子表 public FullName FullName { get; set; } public DataInfo DataInfo { get; set; } }
子表 FullName
public class FullName { public int DrugId { get; set; } // 主键,同时作为父表关联的目标键 public string Name { get; set; } // 导航属性:关联父表 public BasicData BasicData { get; set; } }
子表 DataInfo
public class DataInfo { public int DrugId { get; set; } // 主键,关联父表DrugId public string Size { get; set; } // 导航属性:关联父表 public BasicData BasicData { get; set; } }
Fluent API 关系配置
在你的 DbContext 重写 OnModelCreating 方法,显式配置父表与子表的关联关系,指定复用父表的 DrugId 作为外键:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置 BasicData 与 FullName 的一对一关联 modelBuilder.Entity<BasicData>() .HasOne(b => b.FullName) .WithOne(f => f.BasicData) .HasForeignKey<BasicData>(b => b.DrugId); // 指定父表DrugId为外键,引用FullName的主键DrugId // 配置 BasicData 与 DataInfo 的一对一关联 modelBuilder.Entity<BasicData>() .HasOne(b => b.DataInfo) .WithOne(d => d.BasicData) .HasForeignKey<BasicData>(b => b.DrugId); // 若允许子表数据不存在(可选),添加 .IsRequired(false) // 示例: // modelBuilder.Entity<BasicData>() // .HasOne(b => b.FullName) // .WithOne(f => f.BasicData) // .HasForeignKey<BasicData>(b => b.DrugId) // .IsRequired(false); }
LINQ Include 导航查询
配置完成后,即可通过 Include 方法一次性加载父表及关联子表的数据:
// 查询单个 BasicData 及其关联的 FullName 和 DataInfo var targetData = context.BasicData .Include(b => b.FullName) .Include(b => b.DataInfo) .FirstOrDefault(b => b.DrugId == 1); // 查询所有 BasicData 及其关联子表 var allData = context.BasicData .Include(b => b.FullName) .Include(b => b.DataInfo) .ToList();
关键说明
- 复用父表的
DrugId作为外键,避免了冗余的重复列(如原代码中的FullNameDrugId、DataInfoDrugId),符合数据库设计范式。 - 由于子表的
DrugId是主键,因此这里的关联关系为一对一;若需支持一对多,需调整子表主键设计(例如新增独立主键,将DrugId设为普通外键列)。
内容的提问来源于stack exchange,提问作者Alamzaib Farooq
相关产品推荐
相关产品推荐

