Расширение IdentityUser не загружает добавленные поля - PullRequest
0 голосов
/ 07 апреля 2020

Я использую Asp. Net и Microsoft Identity. Я расширяю IdentityUser для добавления дополнительной информации.

Переопределение моего IdentityUser:

using Microsoft.AspNetCore.Identity;

namespace DASBlazorSite.Data
{
    public class SiteUser : IdentityUser
    {
        public SiteUser() : base()
        {
        }

        public AspNetUserDetail UserData { get; set; }
    }
}

AspNetUserDetail:

using System;
using System.ComponentModel.DataAnnotations;

namespace DASBlazorSite.Data
{
    public class AspNetUserDetail
    {
        [Key]
        public Guid Id { get; set; }

        [StringLength(50)]
        public string FirstName { get; set; }

        [StringLength(50)]
        public string MiddleName { get; set; }

        [StringLength(50)]
        public string LastName { get; set; }
    }
}

После выполнения обновления надстройки- вещь базы данных, я вижу, как создается таблица AspNetUserDetail. Я также вижу дополнительный столбец в AspNetUsers, UserDataId.
Когда я изменяю пользователя и сохраняю его с UserManager.UpdateAsync(SiteUser), я вижу GUID, заполненный в AspNetUsers, и соответствующий GUID в AspNetUserDetail. Я также вижу соответствующие значения для FirstName, et c. также заполняется в AspNetUserDetail.
На данный момент все выглядит хорошо. Тем не менее, когда я получаю пользователя через UserManager, поле UserData становится пустым.
Является ли это чем-то вроде Entity Framework для ленивой / энергичной загрузки? Любые предложения о том, как бы я решил исправить это?
Как ни странно, если я загружаю пользователя, затем установите ноль UserData в new AspNetUserDetail и заполните соответствующие значения, затем выполните UserManager.UpdateAsync(SiteUser) an В таблице AspNetUserDetail создается совершенно новая запись. У него новый GUID, и поле UserDataId теперь указывает на него. Предыдущая запись в AspNetUserDetail теперь осиротела.

1 Ответ

0 голосов
/ 07 апреля 2020

Связанные объекты никогда не загружаются автоматически. Вы должны либо загружать их с нетерпением, используя Include, либо полагаться на отложенную загрузку (которая не включена по умолчанию и вообще не рекомендуется использовать). Проблема здесь заключается в том, что UserManager не предоставляет средств для создания соединений через Include. Вы можете go опередить и включить отложенную загрузку, но это фактически приведет к тому, что при обращении к свойству будет выдан новый запрос. Это может привести к проблеме запроса N + 1 при выполнении таких операций, как итерации, и может быстро выйти из-под контроля, чтобы полностью забить вашу базу данных. Вот почему ленивая загрузка не рекомендуется: слишком сложно гарантировать, что вы эффективно запрашиваете базу данных, и не очевидно, что вы этого не делаете.

Лучшее, что нужно сделать, если вы находитесь в ситуации где нужно для загрузки связанной сущности на пользователя, это просто использовать контекст напрямую, а не UserManager:

var user = await _context.Users.Include(x => x.AspNetUserDetail).SingleOrDefaultAsync(x => x.Id == userId);

С учетом всего сказанного вы создаете проблема там, где ее нет. Весь смысл наличия расширяемого пользовательского объекта заключается в том, чтобы иметь возможность добавлять дополнительные данные непосредственно в этот объект . Вы не должны использовать класс «профиль», как это, во-первых. Введите имя, фамилию и т. Д. c. свойства непосредственно в сущности SiteUser, и тогда вам нечего присоединять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...