您可以在我之前的帖子中看到我的数据库图表:MVC EF - Update navigation property
我想删除并插入一个帖子的类别。 我收到错误收集被修改;枚举操作可能无法执行。在行
foreach (PostMapping pm in current_list_category)
这是我的功能:
//
// POST: /BlogPost/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Post post, int[] selectedCategories)
{
if (ModelState.IsValid)
{
List<PostMapping> current_list_category = db.PostMappings.Where(p => p.PostID == post.ID).ToList();
post.PostMappings = current_list_category;
foreach (PostMapping pm in current_list_category)
{
int categoryId = pm.CategoryID.Value;
if (selectedCategories != null)
{
if (selectedCategories.Contains(categoryId))
{
selectedCategories = selectedCategories.Where(val => val != categoryId).ToArray();
}
else
{
post.PostMappings.Remove(pm);
Category category = db.Categories.Where(c => c.ID == categoryId).SingleOrDefault();
category.PostMappings.Remove(pm);
}
}
}
foreach (var id in selectedCategories)
{
Category category = db.Categories.Where(c => c.ID == id).SingleOrDefault();
PostMapping postMap = new PostMapping();
postMap.Category = category;
postMap.Post = post;
postMap.ID = Guid.NewGuid();
post.PostMappings.Add(postMap);
category.PostMappings.Add(postMap);
}
db.Entry(post).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}
还有其他方法吗?
我不会再得到错误,但现在我还有另一个问题。
在更新之前,我在数据库中有这个:
PostID CategoryID
1 1
1 2
1 3
,但在我更新后(我想删除带有ID 1,2,3的类别并添加ID为4的类别)
PostID CategoryID
1 NULL
1 NULL
1 NULL
1 4
为什么?
我尝试了另一种方法但没有成功:
.....
Post post2 = db.Posts.Where(p => p.ID == post.ID).SingleOrDefault();
post2.PostMappings.Remove(pm);
Category category = db.Categories.Where(c => c.ID == categoryId).SingleOrDefault();
category.PostMappings.Remove(pm);
.....
代替:
....
post.PostMappings.Remove(pm);
Category category = db.Categories.Where(c => c.ID == categoryId).SingleOrDefault();
category.PostMappings.Remove(pm);
.....
但是我收到错误: AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保键值是唯一的。
答案 0 :(得分:3)
枚举时无法更改集合 所以你需要临时收集并枚举它。 像这样的东西:
post.PostMappings = current_list_category;
List<PostMapping> temp = new List<PostMapping>();
temp.AddRange(current_list_category);
foreach (PostMapping pm in temp)
{
int categoryId = pm.CategoryID.Value;
if (selectedCategories != null)
{
if (selectedCategories.Contains(categoryId))
{
selectedCategories = selectedCategories.Where(val => val != categoryId).ToArray();
}
else
{
post.PostMappings.Remove(pm);
Category category = db.Categories.Where(c => c.ID == categoryId).SingleOrDefault();
category.PostMappings.Remove(pm);
}
}
}
甚至更好,特别是如果您只有少量要移除的项目,您可以在单独的列表中收集已删除的项目,然后枚举该列表并从源列表中删除项目
根据帖子编辑进行更改:
您还需要将已删除的条目标记为EntityState.Deleted
答案 1 :(得分:1)
最后我有答案。
我希望这会对某人有所帮助。
//
// POST: /BlogPost/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Post post, int[] selectedCategories)
{
if (ModelState.IsValid)
{
List<PostMapping> current_list_category = db.PostMappings.Where(p => p.PostID == post.ID).ToList();
List<PostMapping> temp = new List<PostMapping>();
temp.AddRange(current_list_category);
if (selectedCategories != null)
{
foreach (PostMapping pm in temp)
{
int categoryId = pm.CategoryID.Value;
if (selectedCategories.Contains(categoryId))
{
selectedCategories = selectedCategories.Where(val => val != categoryId).ToArray();
}
else
{
post.PostMappings.Remove(pm);
db.Entry(pm).State = EntityState.Deleted;
}
}
}
else
{
foreach (PostMapping pm in temp)
{
int categoryId = pm.CategoryID.Value;
post.PostMappings.Remove(pm);
db.Entry(pm).State = EntityState.Deleted;
}
}
if (selectedCategories != null)
{
foreach (var id in selectedCategories)
{
Category category = db.Categories.Where(c => c.ID == id).SingleOrDefault();
PostMapping postMap = new PostMapping();
postMap.Category = category;
postMap.Post = post;
postMap.ID = Guid.NewGuid();
post.PostMappings.Add(postMap);
category.PostMappings.Add(postMap);
}
}
db.Entry(post).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}