Быстрая загрузка с помощью UserManager с ядром EF

#c# #asp.net-core #entity-framework-core

#c# #asp.net-core #entity-framework-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();
  

Но это не отображается правильно для меня!

Есть идеи?

Комментарии:

1. Используйте var userId = _userManager.GetUserId(HttpContext.User) вместо этого, то есть не запрашивая базу данных, а затем выполните быструю загрузку.

Ответ №1:

проверка исходного кода [UserManager][1] GetUserAsync завершится вызовом FindByIdAsync , который будет предоставлен IUserStore реализацией. Просматривая исходный код в вопросе, очень вероятно, используя EFCore в качестве реализации IUserStore.

В случае EFCore здесь упоминалось, что Find его нельзя комбинировать с include , поэтому я спрашиваю, что вы сделали, чтобы выполнить быструю загрузку в вашем вопросе, на самом деле может быть правильным.

Ответ №2:

Если вам нужны эти свойства в каждом запросе, есть лучший способ получить их, не запрашивая базу данных в каждом запросе.

Вы можете сохранить эти свойства, Claims написав свои собственные IUserClaimsPrincipalFactory<TUser> и прочитав их из HttpContext.User

 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;
    }
}
  

Также вам необходимо зарегистрировать его в service collection

 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);
};