首页 > 解决方案 > EF Core 更新外键不会更新导航属性

问题描述

我有一个名为的表User,其中包含 3 个外键CountryIDNationalityID并且EducationID

用户可以更新这些外键中的任何一个,并且端点应该返回更新后的用户实体以及导航属性的详细信息。

所以为了实现这一点,我做了如下

var user= await _dbContext.Users
.Include(x => x.Country)
.Include(x => x.Nationality)
.Include(x => x.Education)
.Where(P => P.userID == request.userId)
.AsTracking()
.FirstOrDefaultAsync();

然后如果用户想更新我做

user.CountryID= request.CountryID;

user.NationalityID= request.NationalityID;

await _dbContext.SaveChangesAsync();

var userDTO = _mapper.Map<UpdateUserResponseDTO>(user);

问题是在 JSON 响应中,国家和国籍详细信息(例如他们的姓名和其他详细信息)返回为null

我所做的修复它是添加

_dbContext.Entry(user).Reference(x => x.Country).Load();

_dbContext.Entry(user).Reference(x => x.Nationality).Load();

_dbContext.Entry(user).Reference(x => x.Education).Load();

await _dbContext.SaveChangesAsync();

但不确定使用有什么影响load或效果如何efficient?为什么asTracking不跟踪导航属性中所做的更改?并且使用Load()更有效,而不是在更新后再次加载用户实体?喜欢做

 var user= await _dbContext.Users
    .Include(x => x.Country)
    .Include(x => x.Nationality)
    .Include(x => x.Education)
    .Where(P => P.userID == request.userId)
    .FirstOrDefaultAsync();

标签: c#linqasp.net-coreentity-framework-core

解决方案


确保在任何 Dbset 属性之前在您的 Context 类中添加 virtual 关键字,如下所示

public virtual DbSet<type> propname {get;set;}

并且还在您的域类中的导航属性之前添加虚拟关键字,就像这样

public class User
{
public virtual Country Country {get;set;} 
}
public class Country 
{
public virtual ICollection<User> Users {get;set;} 
} 

这些配置将帮助实体框架继承您的导航属性并对其应用延迟加载


推荐阅读