在ASP.NET MVC更新导航属性 [英] Update navigation properties in ASP.NET MVC

查看:1030
本文介绍了在ASP.NET MVC更新导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以看到我的previous后我的数据库图表: MVC EF - 更新导航物业

You can see my database diagram on my previous post: MVC EF - Update navigation property

我要删除和插入类别一个职位。
我得到的集合已修改的错误;枚举操作可能不会执行的。在行

I want to delete and insert categories for one post. I get the error Collection was modified; enumeration operation may not execute. at the row

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

有另一种方法呢?

Is there another approach?

我不明白了错误,但现在我有另一个问题。

I don't get anymore the error but now I have another problem.

更新之前我在数据库中有这样的:

Before updating I have this in database:

类别id帖子ID结果
1 1结果
1 2结果
1 3

PostID CategoryID
1 1
1 2
1 3

,但在我更新(我想与IDS 1,2,3删除类别和ID 4添加类别)

, but after I update(I want to remove categories with ids 1,2,3 and add category with id 4)

类别id帖子ID结果
1 NULL结果
1 NULL结果
1 NULL结果
1 4

PostID CategoryID
1 NULL
1 NULL
1 NULL
1 4

为什么?

我试过另一种方法,但没有更迭:

I tried another approach but with no succes:

.....
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的前唯一的。

推荐答案

您不能在你枚举改变它集合
所以你需要临时收集并列举了它。
是这样的:

You can't change collection while you enumerating it so you need temporary collection and enumerate over it. something like this:

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

        }

甚至更好,特别是如果你有只删除一些项目,你可以收集在单独的列表中删除的项目,然后枚举该名单,并从源列表中删除项目

Or even better especially if you have just few items for remove, you can collect removed items in separate list and then enumerate over that list and remove item from source list

据早报编辑:所做的更改

您还需要标记你删除的条目状态 EntityState.Deleted

you also need to mark your removed entries state as EntityState.Deleted

这篇关于在ASP.NET MVC更新导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆