【发布时间】:2015-02-12 16:59:39
【问题描述】:
所以我正在进行一个项目,我需要在团队和成员之间建立多对多关系。
一个团队可以有多个用户(来自 aspnetusers),一个用户可以有 0 个或多个团队。
但目前,一个团队可以有很多用户,但一个用户只能有 1 个团队,每当我尝试在新团队中添加用户时,该用户就会从他所在的团队中删除。
感谢http://cpratt.co/associating-related-items-in-a-collection-via-a-listbox/
我的团队模型:
public class EquipaModel
{
[Key]
public int EquipaID { get; set; }
[Required]
[Display (Name="Nome")]
public string EquipaNome { get; set; }
[Required]
[Display (Name="Descrição")]
public string EquipaDescricao { get; set; }
[Display(Name = "Team Manager")]
public string TeamManagerId { get; set; }
public virtual ApplicationUser TeamManager { get; set; }
public virtual ICollection<ApplicationUser> Membros { get; set; }
}
我的扩展用户模型
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager
.CreateIdentityAsync(this,
DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public virtual Utilizador Utilizador { get; set; }
}
[Table("Utilizadores")]
public class Utilizador
{
public int Id { get; set; }
public string PrimeiroNome { get; set; }
public string Apelido { get; set; }
public int Pontuacao { get; set; }
public int PaisID { get; set; }
public virtual PaisModel Pais { get; set; }
//public IEnumerable<LinguasProgModel> Linguagens { get; set; }
}
我的团队视图模型
public class EquipasViewModel
{
[Required]
public string EquipaNome { get; set; }
public string EquipaDescricao { get; set; }
public string TeamManagerId { get; set; }
public virtual ApplicationUser TeamManager { get; set; }
[Required]
public List<string> MembrosID { get; set; }
public IEnumerable<SelectListItem> MembrosEscolhidos { get; set; }
}
我在 EquipaController (TeamController) 上创建
public ActionResult Create()
{
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email");
var model = new EquipasViewModel();
PopulateMembrosEscolhidos(model);
return View(model);
}
[HttpPost]
public ActionResult Create(EquipasViewModel model)
{
if (ModelState.IsValid)
{
var equipa = new EquipaModel
{
EquipaNome = model.EquipaNome,
EquipaDescricao = model.EquipaDescricao,
TeamManagerId = model.TeamManagerId,
Membros = db.Users.Where(m => model.MembrosID.Contains(m.Id)).ToList()
};
db.Equipas.Add(equipa);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email", model.TeamManagerId);
PopulateMembrosEscolhidos(model);
return View(model);
}
最后是我的团队控制器上的编辑
public ActionResult Edit(string id)
{
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email");
var equipa = db.Equipas.FirstOrDefault(e => e.EquipaNome == id);
if (equipa == null)
{
return new HttpNotFoundResult();
}
var model = new EquipasViewModel
{
EquipaNome = equipa.EquipaNome,
EquipaDescricao = equipa.EquipaDescricao,
MembrosID = equipa.Membros.Select(m => m.Id).ToList()
};
PopulateMembrosEscolhidos(model);
return View(model);
}
[HttpPost]
public ActionResult Edit(string id, EquipasViewModel model)
{
var equipa = db.Equipas.FirstOrDefault(e => e.EquipaNome == id);
if (equipa == null)
{
return new HttpNotFoundResult();
}
if (ModelState.IsValid)
{
equipa.EquipaNome = model.EquipaNome;
equipa.EquipaDescricao = model.EquipaDescricao;
equipa.Membros.Where(m => !model.MembrosID.Contains(m.Id))
.ToList()
.ForEach(m => equipa.Membros.Remove(m));
var MembrosNaEquipa = equipa.Membros.Select(m => m.Id);
var NovosMembros = model.MembrosID.Except(MembrosNaEquipa);
db.Users.Where(m => NovosMembros.Contains(m.Id))
.ToList()
.ForEach(m => equipa.Membros.Add(m));
db.Entry(equipa).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
PopulateMembrosEscolhidos(model);
return View(model);
}
在某些时候,我将删除选择列表并将其替换为用户输入用户名以添加到团队成员列表的文本框 - 但目前我只是想弄清楚如何保存多对多关系。
编辑
我有一种感觉,这很简单,但就是做不到。我开始使用该解决方案,但遇到了一个老实说我从未见过的错误。
Multiplicity constraint violated. The role 'ApplicationUser_Equipas_Source' of the relationship 'Codings.Models.ApplicationUser_Equipas' has multiplicity 1 or 0..1.
它发生在“db.Equipas.Add(equipa);”行的创建。
这可能是我的错误,因为我试图简单地向用户添加一个团队
var MembrosEscolhidos = db.Users.Where(m => model.MembrosID.Contains(m.Id)).ToList();
foreach (var item in MembrosEscolhidos)
{
item.Equipas.Add(equipa);
}
【问题讨论】:
-
您会看到如何在团队模型中引用用户,例如“public virtual ICollection
Membros { get; set; }”... 为什么不在您的用户模型中做同样的事情,而是通过以下方式引用 Teams 模型:“public virtual ICollection Teams { get; set; }”还是我缺少什么?
标签: c# asp.net-mvc entity-framework