ASP.NET Core Identity UserManager 返回用户而不包含相关对象(延迟加载)
Posted
技术标签:
【中文标题】ASP.NET Core Identity UserManager 返回用户而不包含相关对象(延迟加载)【英文标题】:ASP.NET Core Identity UserManager returns user without including related objects (Lazy Loading) 【发布时间】:2021-06-18 03:20:24 【问题描述】:我有一个自定义用户类 User
派生自 IdentityUser
:
public class User : IdentityUser
public UserInfo Info get; set;
我使用了一个UserInfo
类和两个子类来根据用户类型存储额外的用户信息:
public class UserInfo
public int Id get; set;
public string FirstName get; set;
public string LastName get; set;
public bool IsArchived get; set; = false;
public class StudentInfo : UserInfo
public List<Enrollment> Enrollments get; set;
public class InstructorInfo : UserInfo
public List<Department> Departments get; set;
在UsersController
的Account()
操作中,我使用注入的UserManager
实例从用户存储中获取用户:
public class UsersController
private readonly UserManager<User> usrMgr;
private readonly RoleManager<IdentityRole> roleMgr;
public UsersController(UserManager<User> usrMgr, RoleManager<IdentityRole> roleMgr)
=> (this.usrMgr, this.roleMgr) = (usrMgr, roleMgr);
[Authorize]
public async Task<IActionResult> Account()
User user = await userManager.GetUserAsync(this.User); // Here user.Info is null
return user is null ? NotFound() : View(user);
问题在于GetUserAsync(this.User)
方法不包含UserInfo
属性,而是将其保留为null
。 FindByIdAsync(userId)
也不包括它。如果这是DbContext
,我可以使用.Include()
,但我不太清楚如何告诉UserManager
在此处包含相关属性。
【问题讨论】:
你有一个自定义的User
,所以你也应该创建一个自定义的UserManager
,这样你就可以覆盖GetUserAsync
方法来包含你的扩展信息。否则(不创建任何自定义UserManager
),您需要直接使用 DbContext。
King King 是正确的。您正在使用的用户管理器基于IdentityUser
而不是您的User
派生自IdentityUser
,因此它对UserInfo
一无所知。替代覆盖用户管理器方法,您可以访问属性Users
是用户的IQueryable
并直接在其上执行数据库查询。这种方法的优点是您可以轻松地将Include()
链接到它,并且感谢UserInfo
的负载。
@KingKing 谢谢你的建议。我不知道UserManager
也必须扩展,以前从未遇到过这种情况。
@Prolog 我真的很喜欢使用UserManager.Users
的想法。这就是我现在正在使用的:await userManager.Users.Include(usr => usr.UserInfo).FirstOrDefaultAsync(usr => usr.Id == userManager.GetUserId(this.User));
谢谢 :)
【参考方案1】:
正如King King 所提到的,创建自定义UserManager
似乎是要走的路。但是,我最终使用的是Prolog 提到的更简单的方法,它使用UserManager.Users
属性,这是一个IQueryable
,因此可以在其上调用Include()
方法:
await userManager
.Users
.Include(usr => usr.UserInfo)
.FirstOrDefaultAsync(usr => usr.Id == userManager.GetUserId(this.User));
【讨论】:
以上是关于ASP.NET Core Identity UserManager 返回用户而不包含相关对象(延迟加载)的主要内容,如果未能解决你的问题,请参考以下文章
“Identity.External”的 ASP.NET Core 标识异常
ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 14. ASP.NET Core Identity 入门
ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色