AspNetCore.Identity UserManager CreateAsync не может сохранить отношения - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть такая модель:

public class UserIdentity : IdentityUser
{
    public User User { get; set; }
}

public class User : Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public DateTime DateOfBirth { get; set; }
    public Occupation Occupation { get; set; }
    public Country Country { get; set; }
    public City City { get; set; }
    public Ethnicity Ethnicity { get; set; }
    public GenderEnum Gender { get; set; }
}

IdentityUser находится в AspNetCore.Identity пространстве имен.Кроме того, я использую Urf.Core для своего хранилища и сервисного уровня, а Entity предназначен для указания отслеживаемых сущностей в этой библиотеке.

на моем прикладном уровне у меня есть сервис для регистрациипользователи и я использую UserManager<UserIdentity> для сохранения пользователей.

public async Task Register(UserRegistrationDto dto)
    {
        var newUser = new User();

        var country = GetCountry(dto.CountryName);
        var city = GetCity(country, dto.CityName, dto.CityId.Value);

        var ethnicity = GetEthnicity(dto.EthnicityId.Value);
        var occupation = GetOccupation(dto.OccupationId.Value);

        newUser.Country = country;
        newUser.City = city;
        newUser.Occupation = occupation;
        newUser.Ethnicity = ethnicity;

        newUser.DateOfBirth = dto.DateOfBirth;

        newUser.Name = dto.Name;
        newUser.Surname = dto.Surname;
        newUser.Gender = (GenderEnum)dto.Gender.Value;

        _userService.Insert(newUser);

        var newIdentity = new UserIdentity {UserName = dto.Email, Email = dto.Email, User = newUser};
        var result = await _userManager.CreateAsync(newIdentity, dto.Password);

        //await _unitOfWork.SaveChangesAsync();
    }

Объяснение кода:

GetCountry и GetCity, оба проверьте, если город иСтрана существует или нет, а если нет, то создает их.Я вставляю пользователя и все его отношения со службой Urf в _userService.Insert(newUser) и сохраняю все это вместе в одной транзакции с единицей работы Urf, await _unitOfWork.SaveChangesAsync()

Проблема:

размещение SaveChangesAsync() перед _userManager.CreateAsync(), создает пользователя, город, страну и все без проблем.Но если я вызываю _userManager.CreateAsync(), ef выдает исключение «Невозможно вставить явное значение для столбца идентификаторов ...» для столбца идентификатора в таблицах страны, города и пользователя.

Я хочу сохранить UserIdentity иостальные отношения в одном вызове SaveChanges(), но похоже, что _userManager.CreateAsync() не может сохранить отношения, как _unitOfWork.SaveChangesAsync() может.

Временное решение:

чтобы получить проход, я поменял отношения в UserIdentity и User, сначала я создаю идентичность и, если это удается, я вставляю остальные из них:

    public async Task Register(UserRegistrationDto dto)
    {
        var newIdentity = UserIdentity.CreateIdentity(dto.Email, dto.Email, dto.Phone);
        var result = await _userManager.CreateAsync(newIdentity, dto.Password);
        if (result.Succeeded)
        {
            var newUser = new User();

            var country = GetCountry(dto.CountryName);
            var city = GetCity(country, dto.CityName, dto.CityId.Value);

            var ethnicity = GetEthnicity(dto.EthnicityId.Value);
            var occupation = GetOccupation(dto.OccupationId.Value);

            newUser.Identity = newIdentity;
            newUser.Country = country;
            newUser.City = city;
            newUser.Occupation = occupation;
            newUser.Ethnicity = ethnicity;

            newUser.DateOfBirth = dto.DateOfBirth;

            newUser.Name = dto.Name;
            newUser.Surname = dto.Surname;
            newUser.Gender = (GenderEnum)dto.Gender.Value;

            _userService.Insert(newUser);

            await _unitOfWork.SaveChangesAsync();
        }
    }

но, как вы можете видеть, этосохраняет их в двух отдельных транзакциях, если по какой-либо причине произошел сбой _unitOfWork.SaveChangesAsync();, была создана личность и я не могу откатить (возможно, но грязно)

Кто-нибудь знает, почему возникла проблема, которую я объяснил?

1 Ответ

0 голосов
/ 11 февраля 2019

Вы забыли опубликовать свой полный контроллер, особенно сервисы, которые вводятся, но, исходя из вашей проблемы, я предполагаю, что вы вводите UserManager<IdentityUser>.

Параметр типа здесь - это то, чтофактически будет извлечен, сохранен и т. д. Итак, если вы попытаетесь сохранить экземпляр UserIdentity, он будет повышен до IdentityUser (у которого нет вашего свойства User) и , что - это то, что будет создано.Если вам нужно работать с UserIdentity, то вам нужно ввести UserManager<UserIdentity>.

Однако ваш дизайн здесь совершенно неправильный.Смысл универсального пользовательского типа в том, чтобы обеспечить расширяемость.Вы должны создать класс, который наследуется от IdentityUser и указать любые дополнительные свойства для вашего пользователя прямо там.Вам не нужно и не должно быть отдельного класса стиля профиля, добавленного в композицию.Другими словами:

public class User : IdentityUser
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public DateTime DateOfBirth { get; set; }
    public Occupation Occupation { get; set; }
    public Country Country { get; set; }
    public City City { get; set; }
    public Ethnicity Ethnicity { get; set; }
    public GenderEnum Gender { get; set; }
}

Затем в Startup.cs:

services.AddDefaultIdentity<User>();

И в вашем контроллере введите UserManager<User> и работайте с User напрямую.UserIdentity уходит в мусор.

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