У меня есть такая модель:
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();
, была создана личность и я не могу откатить (возможно, но грязно)
Кто-нибудь знает, почему возникла проблема, которую я объяснил?