使用 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));
}
}
}
我将两个多选列表与一个视图模型一起纳入我的编辑操作 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));
}
}
}