繁体   English   中英

使用 UserManager 和 EF Core 快速加载

[英]Eager Loading using UserManager with EF Core

目前有具有一些自定义属性的ApplicationUser类,例如:

public class ApplicationUser : IdentityUser
{
    public string Name { get; set; }
    public List<Content> Content { get; set; }
}

我想通过相关数据列表( Content属性)获取当前登录的用户。

在我的控制器中,如果我输入:

Applicationuser user = await _userManager.GetUserAsync(HttpContext.User);

我得到登录的用户,但没有任何相关数据。 但是,如果我使用ApplicationDbContext检索当前用户,如下所示,我可以检索相关数据:

ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User);
ApplicationUser userWithContent = _context.Users.Include(c => c.Content).Where(u => u.Id == user.Id).ToList();

但这对我来说并不正确!

任何的想法?

检查[UserManager][1]的源代码,GetUserAsync将最终调用FindByIdAsync ,它将由IUserStore实现提供。 查看问题中的源代码,很可能使用EFCore作为IUserStore实现。

在EFCore的情况下, 这里提到Find不能与include结合使用,所以我客人做了什么,在你的问题中急切加载,可能实际上是正确的。

如果您在每个请求中都需要这些属性,则有更好的方法来获取它们,而无需在每个请求中查询数据库。

您可以通过编写自己的IUserClaimsPrincipalFactory<TUser>并从HttpContext.User读取它们来将这些属性存储为Claims

public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public CustomUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, optionsAccessor)
    {

    }

    protected async override Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        ClaimsIdentity identity = await base.GenerateClaimsAsync(user);
        identity.AddClaim(new Claim("Name", user.Name));

        for (int i = 0; i < user.Content.Count; i++)
        {
            string content = Newtonsoft.Json.JsonConvert.SerializeObject(user.Content[i]);
            identity.AddClaim(new Claim("Content", content));
        }

        return identity;
    }
}

您还需要将其注册到服务集合

services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomUserClaimsPrincipalFactory>();

您可以使用此代码访问这些属性

string name = httpContext.User.FindFirstValue("Name");

List<Content> contents = new List<Content>();
foreach (Claim claim in httpContext.User.FindAll("Content"))
{
    Content content = Newtonsoft.Json.JsonConvert.DeserializeObject<Content>(claim.Value);
    contents.Add(content);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM