如何正确加载带外键的EF Core实体的virtual虚拟导航属性
问题修复方案
1. 移除导航属性上的[NotMapped]特性
[NotMapped]的作用是通知EF Core完全忽略对应属性,既不会做数据库字段映射,也不会处理关联关系加载,这是你所有导航属性全为null的核心原因。
需要删除以下位置的[NotMapped]标记:
Death类的Person属性Work类的Person、Title属性Person类的Works、Death属性
2. 修正一对一外键的重复配置
你在Person和Death的实体配置中重复定义了一对一关系的外键规则,造成配置冲突,仅保留单侧配置即可,删除Death实体配置中以下重复代码:
builder.HasOne(x => x.Person).WithOne(x => x.Death).HasForeignKey<Person>(x => x.Id);
保留Person实体中的builder.HasOne(x => x.Death).WithOne(x => x.Person).HasForeignKey<Death>(x => x.PersonId);即可,符合Death表主键为PersonId的结构设计。
3. 显式加载关联导航属性
EF Core默认不会自动加载关联数据,你可以选择两种实现方式:
方式1:查询时使用Include显式加载(推荐,性能可控)
修改你的GetPerson方法,Find方法无法配合Include使用,替换为FirstOrDefault即可:
public Person GetPerson(string Id) { return Context.Persons .Include(p => p.Death) .Include(p => p.Works) .FirstOrDefault(p => p.Id == Id); }
方式2:开启懒加载
如果需要自动加载导航属性,可以开启懒加载能力:
- 安装Nuget包
Microsoft.EntityFrameworkCore.Proxies - 在
OnConfiguring中添加配置:
optionsBuilder.UseLazyLoadingProxies();
你当前所有导航属性已经用virtual修饰,满足懒加载的要求。
4. 可选优化
如果选择懒加载方案,可以移除Person构造函数中Works的初始化代码,EF Core会自动初始化集合导航属性,手动初始化可能覆盖懒加载代理实现。
内容的提问来源于stack exchange,提问作者Alexis Choupault
相关产品推荐
相关产品推荐

