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; 

UsersControllerAccount() 操作中,我使用注入的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 属性,而是将其保留为nullFindByIdAsync(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 =&gt; usr.UserInfo).FirstOrDefaultAsync(usr =&gt; 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 中获取用户角色

Asp.Net Core 2.1 Identity - UserStore 依赖注入

ASP.NET Core Identity 系列之四

ASP.NET Core Identity - 扩展密码哈希