使用 Entity Framework 删除对象列表并有效添加新对象

Remove a list of objects and add new ones efficiently using Entity Framework

我将两个多选列表与一个视图模型一起纳入我的编辑操作 Post 方法。对于每个多选,我想遍历每个对象并删除未选中的内容并添加已选中的内容。

在本例中,我在项目中添加和删除属于特定角色类型的用户。最初我在考虑 db.SaveChages() 每次迭代,但这似乎效率低下?对更好的方法有什么建议吗?目前这是行不通的...请原谅我离题太远,这是我学习 MVC 的第 4 周。提前致谢!

   // POST: Projects/Edit
    [HttpPost]
    [ValidateAntiForgeryToken]
    [Authorize(Roles = "Administrator")]
    public ActionResult Edit(ProjectEditViewModel vm, int ProjectStatusId)
    {
        if (ModelState.IsValid)
        {
            var project = db.Project.Find(vm.ProjectId);

            project.Name = vm.ProjectName;

            project.ProjectStatusId = ProjectStatusId;

            var users = db.Users.Where((u => u.Projects.Any(ui => ui.ProjectId == vm.ProjectId)));

            var currentDevs = users.Where(u => u.Roles.Any(ur => ur.RoleId == db.Roles.FirstOrDefault(r => r.Name == "Developer").Id));

            var currentPMs = users.Where(u => u.Roles.Any(ur => ur.RoleId == db.Roles.FirstOrDefault(r => r.Name == "Project_Manager").Id));

            if (currentDevs != null)
            {
                foreach (var cd in currentDevs)
                {
                    project.Users.Remove(cd);

                }                   
            }
            if (currentPMs != null)
            {
                foreach (var cpm in currentPMs)
                {
                    project.Users.Remove(cpm);

                }
            }

            if (vm.SelectedDevs != null)
            {
                foreach (var dev in vm.SelectedDevs)
                {
                    var developer = users.FirstOrDefault(a => a.DisplayName == dev);

                    project.Users.Add(developer);
                }
            }

            if (vm.SelectedPMs != null)
            {
                foreach (var pm in vm.SelectedPMs)
                {
                    var projMgr = users.FirstOrDefault(a => a.DisplayName == pm);

                    project.Users.Add(projMgr);
                }
            }

            db.Entry(project).State = EntityState.Modified;

            db.SaveChanges();

            return RedirectToAction("Details", new { id = vm.ProjectId });
        }

        return View(vm);
    }

这应该适合你。您不想每次都删除所有用户并重新添加他们。这会导致很多问题。相反,您仅删除已取消选择的那些,然后仅添加新选择的(之前列表中不存在的)。

var devRoleId = db.Roles.FirstOrDefault(r => r.Name == "Developer").Id;
var pmRoleId = db.Roles.FirstOrDefault(r => r.Name == "Project_Manager").Id;

// Remove de-selected devs
project.Users.Where(u => u.RoleId == devRoleId && !vm.SelectedDevs.Contains(u.DisplayName))
    .ToList().ForEach(u => project.Users.Remove(u));

// Add newly selected devs
var existingDevs = project.Users.Where(u => u.RoleId == devRoleId).Select(m => m.DisplayName);
db.Users.Where(u => vm.SelectedDevs.Exclude(existingDevs).Contains(u.DisplayName))
    .ToList().ForEach(u => project.Users.Add(u));

// Remove de-selected PMs
project.Users.Where(u => u.RoleId == pmRoleId && !vm.SelectedPMs.Contains(u.DisplayName))
    .ToList().ForEach(u => project.Users.Remove(u));

// Add newly selected PMs
var existingPMs = project.Users.Where(u => u.RoleId == pmRoleId).Select(m => m.DisplayName);
db.Users.Where(u => vm.SelectedPMs.Exclude(existingPMs).Contains(u.DisplayName))
    .ToList().ForEach(u => project.Users.Add(u));

我想我会回过头来 post 我对两种角色类型中的一种的解决方案。同样的逻辑也适用于另一个(SO woot 的第一个解决方案!!!)

var devRoleId = db.Roles.FirstOrDefault(r => r.Name == "Developer").Id;
            var users = db.Users.ToList();

            //currently assigned developers
            var currentDevs = (from p in project.Users
                               where p.Roles.Any(r => r.RoleId == devRoleId)
                               select p).ToList();

            // if the new list is null and old list is not null, remove the old list members
                if (vm.SelectedDevs == null)
                {
                    if(currentDevs != null)
                    {
                        foreach (var d in currentDevs)  
                        {
                            project.Users.Remove(d);
                        }
                    }
                }                

            //if the new list is not null 
                if (vm.SelectedDevs != null)   
                {
                    if (currentDevs == null) //if the old list is null, add the new list members
                   {
                       foreach(var nd in vm.SelectedDevs)
                       {
                           project.Users.Add(users.FirstOrDefault( u => u.DisplayName == nd));
                       }
                   }
                   else  //if the old list is not null, compare each new list member to old and if its new list member is truely new, add them
                   {
                        foreach(var nd in vm.SelectedDevs)
                        {
                            if(!currentDevs.Any(cd => cd.DisplayName == nd))
                            project.Users.Add(users.FirstOrDefault( u => u.DisplayName == nd));
                        }
                   }
                }