MVC 5中的多对多关系

时间:2015-02-12 16:59:40

标签: c# asp.net-mvc entity-framework

所以我正处于一个项目的中间,我需要在团队和成员之间建立多对多的关系。

一个团队可以有很多用户(来自aspnetusers),一个用户可以拥有0个或更多团队。

但目前,一个团队可以拥有多个用户,但是一个用户只能拥有一个团队,每当我尝试在新团队中添加用户时,该用户就会从他已经在的团队中删除。

由于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; }

    }

我的团队ViewModel

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.

它发生在线上&#34; db.Equipas.Add(equipa);&#34;创造。

这可能是我的错误,因为我试图通过

向用户添加团队
var MembrosEscolhidos = db.Users.Where(m => model.MembrosID.Contains(m.Id)).ToList();

foreach (var item in MembrosEscolhidos)
                {
                    item.Equipas.Add(equipa);
                }

1 个答案:

答案 0 :(得分:0)

我认为一个简单的解决方法是将您的EquipaModel作为用户表中的集合引用。

e.g。

public virtual ICollection<EquipaModel> Equipas { get; set; }

就像你在EquipaModel中引用你的用户一样

e.g。

public class EquipaModel
{
   ...
   public virtual ICollection<ApplicationUser> Membros { get; set; }
}

然后您的用户可以拥有许多“Equipas”或团队。