[英]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
,例如具有UserId
和SkillId
的 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-Migration
和Update-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.