【问题标题】:Many to Many Relationship on MVC5MVC5 上的多对多关系
【发布时间】: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


【解决方案1】:

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

例如

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

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

例如

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

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

【讨论】:

  • 这当然是有道理的,不知道为什么我没有想到这一点,尽管就像我在编辑时所说的那样,遇到了另一个问题:|
  • 好的,这与您最初遇到的问题不同...试试这个解决您现在遇到的问题stackoverflow.com/questions/20034003/…...
猜你喜欢
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 2019-05-06
  • 2017-11-27
相关资源
最近更新 更多