簡體   English   中英

AspNetCore.Identity UserManager CreateAsync無法保存關系

[英]AspNetCore.Identity UserManager CreateAsync cannot save relationships

我有一個這樣的模型:

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

代碼說明:

GetCountryGetCity ,都檢查城市和國家/地區是否存在,如果不存在,則創建城市和國家/地區。 我將用戶及其與_userService.Insert(newUser)服務的所有關系插入_userService.Insert(newUser) ,並將其全部與單個await _unitOfWork.SaveChangesAsync()工作單元一起保存在單個事務中, await _unitOfWork.SaveChangesAsync()

問題:

SaveChangesAsync()放在_userManager.CreateAsync() SaveChangesAsync()之前,可以_userManager.CreateAsync()創建用戶,城市,國家和所有地區。 但是,如果我調用_userManager.CreateAsync() ,則ef會為國家,城市和用戶表中的id列引發異常“無法為標識列插入顯式值...”。

我想保存UserIdentity的關系和休息的一個調用SaveChanges()但看起來像_userManager.CreateAsync()不能保存喜歡的方式關系_unitOfWork.SaveChangesAsync()即可。

臨時解決方案:

為了UserIdentity獲得通過,我反轉了UserIdentityUser的關系,我首先創建了身份,如果成功,則插入其中的其余部分:

    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();它將保存在兩個單獨的事務中_unitOfWork.SaveChangesAsync(); 由於任何原因而失敗,創建了身份,並且我無法回滾(可能但很臟)

有誰知道為什么我解釋的問題會發生?

您忽略了發布完整的控制器,特別是要注入的服務,但是基於您的問題,我猜測您正在注入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一起User UserIdentityUserIdentity

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM