簡體   English   中英

如何正確擴展 IdentityUser 為每個用戶保存 collections

[英]How to correctly extend IdentityUser to save collections for each user

我希望用戶能夠從 MultiSelectList 下拉列表中選擇 select 多種技能。 我能夠將每個用戶的多個技能選擇保存到數據庫中,但我發現如果我刪除了一個用戶的技能選項,並且我使用之前在他的選擇中保存了相同技能的不同用戶登錄,它會已為此用戶和所有其他保存了類似技能選項的用戶刪除。

只是我很清楚。 假設用戶 A 保存了這些技能 [“C#”、“Python”、“Java”]。 用戶 B 當前保存的技能是 ["C++","Scala"]。 用戶 B 然后登錄並決定添加他剛剛學習的 C#。 一旦他更新了他的個人資料並且他的選擇變成了這個[“C++”,“Scala”,“C#”]。 C# 將從用戶 A 的選擇中刪除,因此它變為 ["Python", "Java"]。

這是我的自定義IdentityUser class。

public class ApplicationUser : IdentityUser
{
    public ApplicationUser()
    {
        Skills = new List<Skill>();
    }
    public string Location { get; set; }
    public virtual ICollection<Skill> Skills { get; set; }
}

這是技能 model。

public class Skill
{
    public int SkillId { get; set; }
    public string SkillType { get; set; }
}

這就是我在 controller 中保存技能選擇的方式。

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
    var user = await _userManager.GetUserAsync(User);

    if (user == null)
    {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }
    if (ModelState.IsValid)
    {
        if (user.Location != profileModel.Location) user.Location = profileModel.Location;

        if (profileModel.SelectedSkillIds != null)
        {
            List<Skill> tempSkills = new List<Skill> { };
            foreach (var skillID in profileModel.SelectedSkillIds)
            {
                user.Skills.Add(_context.Skills.FirstOrDefault(x => x.SkillId == skillID));
                var skill = _context.Skills.Find(skillID);
                if (skill != null)
                {
                    user.Skills.Add(skill);
                    tempSkills.Add(skill);
                }
                var allSkills = _context.Skills.ToList();
                var skillsToRemove = allSkills.Except(tempSkills);
                foreach (var sk in skillsToRemove)
                {
                    user.Skills.Remove(sk);
                }
            }
            await _userManager.UpdateAsync(user);
            await _signInManager.RefreshSignInAsync(user);
            return RedirectToAction("Profile", "Account");
        }
        return View(profileModel);
    }
}

更新 - 我如何刪除選擇

if (profileModel.SelectedSkillIds != null)
{
    List<UserSkill> tempSkills = new List<UserSkill> { };
    foreach (var skillID in profileModel.SelectedSkillIds)
    {
        var skill = _context.Skills.Find(skillID);
        if (skill != null)
        {
            var userskill = new UserSkill { AppUserId = user.Id, SkillId = skill.SkillId };
            user.UserSkills.Add(userskill);
            tempSkills.Add(userskill);
        }
    var allSkills = _context.UserSkills.ToList();
    var skillsToRemove = allSkills.Except(tempSkills);
    foreach (var sk in skillsToRemove)
    {
        user.UserSkills.Remove(sk); 
    }
}

您應該創建一個UserSkills ,例如具有UserIdSkillId的 UserSkills,在這種情況下,任何用戶都可以擁有多種技能,並且任何技能都可以用於許多用戶。 多對多1、2

您應該將您的 model 更改為此

public class ApplicationUser : IdentityUser
{
    public ApplicationUser()
    {
        Skills = new List<Skill>();
    }
    public string Location { get; set; }
    public virtual ICollection<UserSkills> Skills { get; set; }
}
public class Skill
{
    public int SkillId { get; set; }
    public string SkillType { get; set; }
    public virtual ICollection<UserSkills> Skills { get; set; }
}
public class UserSkills
{
    public int Id { get; set }
    public int UserId { get; set }
    public int SkillId { get; set }
    public Skill Skill { get; set; }
    public ApplicationUser User { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
    var user = await _userManager.GetUserAsync(User);

    if (user == null)
    {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }
    if (ModelState.IsValid)
    {
        if (user.Location != profileModel.Location) user.Location = profileModel.Location;

        if (profileModel.SelectedSkillIds != null)
        {
            List<Skill> tempSkills = new List<Skill> { };
            foreach (var sk in user.UserSkills)
            {
               user.UserSkills.Remove(sk);
            }
            foreach (var skillID in profileModel.SelectedSkillIds)
            {
                var userSkills = new UserSkill { UserId = user.Id, SkillId = skillID };
                user.UserSkills.Add(userSkills);
            }
            await _userManager.UpdateAsync(user);
            await _signInManager.RefreshSignInAsync(user);
            return RedirectToAction("Profile", "Account");
        }
        return View(profileModel);
    }
}

然后將UserSkills添加到您的DbContext

public DbSet<Skill> Skills { get; set; }
public DbSet<UserSkill> UserSkills { get; set; }

最后在package manager console中使用Add-MigrationUpdate-DataBase

另一種選擇

您可以在 controller 中注入DbContext並在UserSkill表中添加UserSkills數據

private readonly YourDbContext _dbContext;
public UserController(YourDbContext dbContext)
{
    _dbContext = dbContext;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel profileModel)
{
    var user = await _userManager.GetUserAsync(User);

    if (user == null)
    {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }
    if (ModelState.IsValid)
    {
        if (user.Location != profileModel.Location) user.Location = profileModel.Location;

        if (profileModel.SelectedSkillIds != null)
        {
            var userSkillsForDelete = _dbContext.UserSkills.Where(a => a.UserId == user.Id).ToList();//<-- NOTE THIS
            foreach (var sk in userSkillsForDelete)
            {
               //user.UserSkills.Remove(sk);
               _dbContext.UserSkills.Remove(sk);<--NOTE THIS
            }
            foreach (var skillID in profileModel.SelectedSkillIds)
            {
                var userSkills = new UserSkill { UserId = user.Id, SkillId = skillID };
               _dbContext.UserSkills.Add(userSkills);<--NOTE THIS
            }
            await _userManager.UpdateAsync(user);
            await _signInManager.RefreshSignInAsync(user);
            return RedirectToAction("Profile", "Account");
        }
        return View(profileModel);
    }
}

暫無
暫無

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

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