EF Core 6如何定义基于非主键的实体关联关系?
解决方案
要让Device.Procedures能返回同设备类型下的所有Procedure,需要在MyDbContext的OnModelCreating方法里显式配置这个关联关系——EF Core没法自动识别这种基于共享外键的跨表关联。
具体配置代码
在MyDbContext中重写OnModelCreating,添加以下配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置Device与Procedure基于DeviceTypeID的关联 modelBuilder.Entity<Device>() .HasMany(device => device.Procedures) .WithMany() .UsingEntity<Dictionary<string, object>>( // 关联Procedure端,用自身的DeviceTypeID作为匹配键 j => j.HasOne<Procedure>() .WithMany() .HasForeignKey("DeviceTypeID") .HasPrincipalKey<Procedure>(p => p.DeviceTypeID), // 关联Device端,用自身的DeviceTypeID作为匹配键 j => j.HasOne<Device>() .WithMany() .HasForeignKey("DeviceTypeID") .HasPrincipalKey<Device>(d => d.DeviceTypeID) ); base.OnModelCreating(modelBuilder); }
配置说明
HasMany(device => device.Procedures):声明Device的Procedures是对应多个Procedure的集合导航属性。WithMany():因为我们不需要在Procedure类里加反向的导航属性(比如ICollection<Device>),所以这里留空即可。UsingEntity:这是EF Core处理无中间表多对多关联的方式,通过指定双方的DeviceTypeID作为匹配键,让EF自动关联Device和Procedure中同类型的记录。
验证查询
配置完成后,你写的查询代码就能正常运行:
public Procedure GetFirstProcedureForDevice(MyDbContext dbContext, Guid deviceId) { var device = dbContext.Devices .Include(m => m.Procedures) .First(m => m.ID == deviceId); var procedure = device.Procedures.FirstOrDefault(); return procedure; }
EF Core会自动生成包含Device.DeviceTypeID = Procedure.DeviceTypeID条件的SQL,实现预加载Procedures集合的效果。
内容的提问来源于stack exchange,提问作者Ben Harden
相关产品推荐
相关产品推荐

