ASP.NET/EFCore中如何访问AppUser引用的其他对象属性?
UserManager<TUser>.GetUserAsync() 方法原生不支持直接传入.Include()表达式加载关联导航属性。该方法默认只会查询用户表自身的基元类型字段,不会自动处理EF Core的关联导航属性,这也是你获取到的Inventory属性始终为null的根本原因——默认ASP.NET Core Identity配置不会开启EF Core懒加载代理,未显式加载的导航属性会保持null值。
可落地的实现方案
方案1:直接通过DbContext显式Include查询(最推荐)
直接注入项目中继承自IdentityDbContext的应用数据库上下文,手动编写查询逻辑,通过Include指定要加载的导航属性,一次数据库查询即可拿到完整数据,性能和灵活度最高:
// 先获取当前登录用户的ID var currentUserId = _userManager.GetUserId(User); // 查询时显式关联Inventory表 var user = await _appDbContext.Users .Include(u => u.Inventory) .FirstOrDefaultAsync(u => u.Id == currentUserId);
如果需要加载多层级关联数据、追加查询过滤条件,这种写法都可以直接实现,是实际项目中最常用的处理方式。
方案2:配置自动Include(适合导航属性全局必带的场景)
如果Inventory是每次查询AppUser都需要加载的属性,可以直接在EF Core的模型配置中开启该导航属性的自动加载,后续所有查询AppUser的操作(包括GetUserAsync())都会默认关联加载Inventory数据,不需要每次手写Include:
在你的应用DbContext类中重写OnModelCreating方法,追加如下配置:
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // 配置AppUser的Inventory导航属性自动Include builder.Entity<AppUser>() .Navigation(u => u.Inventory) .AutoInclude(); }
注意:如果个别场景不需要加载Inventory,可以在查询时追加.IgnoreAutoIncludes()临时关闭自动加载逻辑。
方案3:拿到用户实例后手动补加载(仅适合临时场景)
如果已经通过GetUserAsync拿到了用户实例,也可以通过EF Core的Entry API单独加载关联属性,但这种方式会产生两次独立的数据库查询,性能低于一次Join查询,不建议作为常规实现:
var user = await _userManager.GetUserAsync(User); // 显式加载Inventory导航属性 await _appDbContext.Entry(user) .Reference(u => u.Inventory) .LoadAsync();
❌ 不推荐方案:不要通过开启EF Core懒加载代理解决该问题。懒加载会在你首次访问
Inventory属性时隐式发送数据库查询,非常容易引发N+1查询性能问题,线上环境排查和优化成本极高。
内容的提问来源于stack exchange,提问作者Lockster

