更新ASP中的导航属性.净MVC

本文关键字:属性 MVC 导航 ASP 更新 | 更新日期: 2023-09-27 17:50:49

你可以看到我的数据库图在我以前的帖子:MVC EF -更新导航属性

我想为一个帖子删除和插入类别。我得到错误Collection被修改;枚举操作不能执行。在

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 2
1 3

,但在我更新后(我想删除id为1,2,3的类别并添加id为4的类别)

PostID CategoryID
1空
1空
1空
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之前确保键值是唯一的

更新ASP中的导航属性.净MVC

枚举集合时不能更改集合所以你需要临时收集和枚举它。像这样:

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

我终于有答案了。

我希望这能帮助到别人。

        //
    // 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);
    }