EF Core关联实体加载异常:空值与重复记录问题排查
关于EF Core关联实体加载的问题
我在使用EF Core时遇到关联实体加载问题:
- 最初查询User时,关联的UserGovernments始终为空
- 手动修改代码后,又出现UserGovernment记录重复的情况
原代码(UserGovernments为空)
public static User GetUser(int userID) { _context.Users.Where(x => x.UserId == userID) .FirstOrDefault(); }
修改后的代码(出现重复记录)
public static User GetUser(int userID) { using (var _context = new SafetyContext()) { // find lga for this user var user_govs = from o in _context.Users join i in _context.UserGovernments on o.UserId equals i.UserId where o.UserId == userID select new { o, i }; var user = _context.Users .Where(x => x.UserId == userID) .FirstOrDefault(); foreach (var lga in user_govs) { user.UserGovernments.Add(new UserGovernment { UserId = userID, UserGovernmentId = lga.i.UserGovernmentId, LocalGovId = lga.i.LocalGovId, StateId = lga.i.StateId }); } return user; } }
相关模型类
public class User { public int UserId { get; set; } public string Name { get; set; } public string Email { get; set; } public UserAccess AccessLevel { get; set; } public ICollection<UserGovernment> UserGovernments { get; set; } } public class UserGovernment { public int UserGovernmentId { get; set; } public int UserId { get; set; } public User User { get; set; } public int StateId { get; set; } public State State { get; set; } public int LocalGovId { get; set; } public LocalGov LocalGov { get; set; } } public class LocalGov { public int LocalGovId { get; set; } public string Name { get; set; } public string LgaPid { get; set; } public ICollection<UserGovernment> UserGovernments { get; set; } }
上下文配置
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<UserGovernment>() .HasKey(bc => new {bc.UserGovernmentId}); modelBuilder.Entity<UserGovernment>() .HasOne(bc => bc.User) .WithMany(b => b.UserGovernments) .HasForeignKey(bc => bc.UserId); modelBuilder.Entity<UserGovernment>() .HasOne(bc => bc.LocalGov) .WithMany(c => c.UserGovernments) .HasForeignKey(bc => bc.LocalGovId); }
错误原因及解决方法
1. 原代码UserGovernments为空的原因
EF Core默认关闭延迟加载,直接查询User时,导航属性UserGovernments不会被自动填充,必须显式指定加载关联实体。
2. 修改后出现重复记录的原因
执行user_govs查询时,EF Core上下文已经跟踪了查询到的UserGovernment实体;后续手动创建新对象添加到集合时,若上下文通过延迟加载或跟踪机制自动加载了原有关联实体,就会导致重复。
正确的解决方式
使用Include方法显式加载关联实体,这是EF Core加载导航属性的标准做法:
public static User GetUser(int userID) { using (var _context = new SafetyContext()) { return _context.Users .Include(u => u.UserGovernments) // 显式加载关联的UserGovernments .Where(x => x.UserId == userID) .FirstOrDefault(); } }
如果需要进一步加载UserGovernment关联的State或LocalGov,可使用ThenInclude:
return _context.Users .Include(u => u.UserGovernments) .ThenInclude(ug => ug.State) // 加载UserGovernment关联的State .Include(u => u.UserGovernments) .ThenInclude(ug => ug.LocalGov) // 加载UserGovernment关联的LocalGov .Where(x => x.UserId == userID) .FirstOrDefault();
另外,建议在实体构造函数中初始化集合属性,避免空引用异常:
public class User { public User() { UserGovernments = new List<UserGovernment>(); } // 其他属性... public ICollection<UserGovernment> UserGovernments { get; set; } }
内容的提问来源于stack exchange,提问作者Samra
相关产品推荐
相关产品推荐

