Asp.net mvc EF CodeFirst多对多更新(MVC4)

Asp.net mvc EF CodeFirst多对多更新(MVC4),asp.net-mvc,entity-framework,asp.net-mvc-4,Asp.net Mvc,Entity Framework,Asp.net Mvc 4,我跟着这个 这适用于添加我的多对多值 但是,当我尝试使用相同的代码进行编辑时,无论我做什么,它都不会更改多对多值 我的设想是 我有菜单和页面 许多页面可以添加到许多菜单中 我将页面完美地添加到相关菜单中,但在编辑时,每次都会产生相同的值,即使我调用menu.pages.Clear();SaveChanges();它只会在与菜单关联的页面列表上产生与编辑之前相同的值 [HttpPost] public ActionResult Edit(MenuViewModel MenuViewMod

我跟着这个

这适用于添加我的多对多值

但是,当我尝试使用相同的代码进行编辑时,无论我做什么,它都不会更改多对多值

我的设想是

我有菜单和页面

许多页面可以添加到许多菜单中

我将页面完美地添加到相关菜单中,但在编辑时,每次都会产生相同的值,即使我调用menu.pages.Clear();SaveChanges();它只会在与菜单关联的页面列表上产生与编辑之前相同的值

[HttpPost]
    public ActionResult Edit(MenuViewModel MenuViewModel, int PageID, int ActivePosition, int OldAP)
    {
        Service.AddOrUpdateCourses(MenuViewModel.ZMenu, MenuViewModel.Pages);
        ViewBag.Message = Service.CreateOrUpdate<ZMenu>(MenuViewModel.ZMenu, PageID, ActivePosition, OldAP);

        if (ViewBag.Message.ToString() == "true")
        {
            Service.Commit();
            return RedirectToAction("Index");
        }

        ViewBag.ActivePosition = ModuleManager.AvailableModulePositions(OldAP);
        ViewBag.PageID = Service.GetPageSelectList(MenuViewModel.ZMenu.Page.ID);
        return View(MenuViewModel);
    }
[HttpPost]
公共操作结果编辑(MenuViewModel MenuViewModel、int PageID、int ActivePosition、int OldAP)
{
Service.AddOrUpdateCourses(MenuViewModel.ZMenu,MenuViewModel.Pages);
ViewBag.Message=Service.CreateOrUpdate(MenuViewModel.ZMenu,PageID,ActivePosition,OldAP);
if(ViewBag.Message.ToString()=“true”)
{
Commit();
返回操作(“索引”);
}
ViewBag.ActivePosition=ModuleManager.AvailableModulePositions(OldAP);
ViewBag.PageID=Service.GetPageSelectList(MenuViewModel.ZMenu.Page.ID);
返回视图(MenuViewModel);
}
PageID是模块(菜单)所在的页面,ActivePosition是模块所在的位置,OldAP是更新前的位置。 “Z”是预先确定的,因为它是代码中的一般主题,可以避免与任何其他函数的混淆

服务是存储库

public void AddOrUpdateCourses(ZMenu ZMenu, IEnumerable<AssignedPageData> AssignedPages)
    {
        ZMenu.Pages.Clear();
        foreach (var AssignedPage in AssignedPages)
        {
            if (AssignedPage.Assigned)
            {
                var newpage = Context.ZPages.Find(AssignedPage.ID);
                Context.ZPages.Attach(newpage);
                ZMenu.Pages.Add(newpage);
            }
        }
    }
public void AddOrUpdateCourses(ZMenu ZMenu,IEnumerable AssignedPages)
{
ZMenu.Pages.Clear();
foreach(AssignedPages中的var AssignedPages)
{
if(AssignedPage.Assigned)
{
var newpage=Context.ZPages.Find(AssignedPage.ID);
Context.ZPages.Attach(newpage);
ZMenu.Pages.Add(新建页面);
}
}
}
潜在的无用信息。。。另一种方法是

public string CreateOrUpdate<T>(object _Module, int PageID, int ActivePosition, int OldAP = -1)
    {
        Type type = typeof(T);
        dynamic Module = type.DynamicCast(_Module);

        // set the date, depending on if its a create or edit

        if (Module.ID == 0 || Module.ID == null)
            Module.Date = DateTime.Now;
        else
        {
            int ID = Module.ID;
            Module.Date = Context.ZModules.AsNoTracking().Single(x => x.ID == ID).Date;
        }

        Module.Type = Context.ZModuleTypes.Single(x => x.Name == type.Name.Substring(1, type.Name.Length - 1));
        Module.Page = Context.ZPages.Single(x => x.ID == PageID);
        Module.ActivePosition = ActivePosition;

        bool PositionTaken = false;//this.CheckModulePositions<T>(_Module, OldAP);
        if (PositionTaken)
        {
            return "Position " + Module.ActivePosition + " is taken, please select another";
        }
        else
        {
            try
            {
                int ID = Module.ID ?? -1;
                if (Context.ZModules.AsNoTracking().Where(x => x.ID == ID).Count() == 0)
                {
                    Context.Entry(Module).State = System.Data.EntityState.Added;
                }
                else
                {
                    Context.Entry(Module).State = System.Data.EntityState.Modified;
                }

                return "true";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
    }
public string CreateOrUpdate(对象_模块,int PageID,int ActivePosition,int OldAP=-1)
{
类型=类型(T);
动态模块=类型.DynamicCast(_模块);
//设置日期,具体取决于是创建日期还是编辑日期
if(Module.ID==0 | | Module.ID==null)
Module.Date=DateTime.Now;
其他的
{
int ID=Module.ID;
Module.Date=Context.ZModules.AsNoTracking().Single(x=>x.ID==ID).Date;
}
Module.Type=Context.ZModuleTypes.Single(x=>x.Name==Type.Name.Substring(1,Type.Name.Length-1));
Module.Page=Context.ZPages.Single(x=>x.ID==PageID);
Module.ActivePosition=ActivePosition;
bool positiontake=false;//this.CheckModulePositions(\u Module,OldAP);
如果(采取的立场)
{
返回“位置”+Module.ActivePosition+,请选择另一个”;
}
其他的
{
尝试
{
int ID=Module.ID???-1;
if(Context.ZModules.AsNoTracking().Where(x=>x.ID==ID.Count()=0)
{
Context.Entry(Module).State=System.Data.EntityState.Added;
}
其他的
{
Context.Entry(Module.State=System.Data.EntityState.Modified;
}
返回“真”;
}
捕获(例外情况除外)
{
返回ex.消息;
}
}
}
我已经禁用了模块位置保护(每个模块位置1个模块),以防止它成为一个潜在问题,但这并没有解决它,以防万一您想知道为什么我在上面注释了一小行代码

我已经对此进行了调试,当调用Commit()方法时,ZMenu实体具有正确的有问题的页面,但是在这之后,页面列表将恢复到编辑之前的状态。创建时工作

有人有线索吗

如果需要,将提供更多信息

编辑:

这是有问题的ViewModel

public class MenuViewModel
{
    public ZMenu ZMenu { get; set; }
    public virtual ICollection<AssignedPageData> Pages { get; set; }

    public MenuViewModel(ZMenu ZMenu)
    {
        this.ZMenu = ZMenu;
    }

    public MenuViewModel()
    {

    }
}
公共类菜单视图模型
{
公共ZMenu ZMenu{get;set;}
公共虚拟ICollection页{get;set;}
公共菜单视图模型(ZMenu ZMenu)
{
this.ZMenu=ZMenu;
}
公共菜单视图模型()
{
}
}
编辑2:

由于下面的评论和一些继续的工作,代码如下,在似乎是问题的区域,我现在遇到了一个错误,但我不知道如何修复错误

Store update、insert或delete语句影响了意外的行数(0)。自加载实体后,实体可能已被修改或删除。刷新ObjectStateManager条目

public void AddOrUpdateCourses(ZMenu ZMenu,IEnumerable AssignedPages)
{
Context.ZMenuModules.Attach(ZMenu);
HashSet CurrentPages=新HashSet
(ZMenu.Pages.Select(i=>i.ID));
foreach(AssignedPages中的var AssignedPages)
{
ZPage newpage=Context.ZPages.Find(AssignedPage.ID);
Context.ZPages.Attach(newpage);
if(AssignedPage.Assigned)
{
如果(!CurrentPages.Contains(AssignedPage.ID))
{
ZMenu.Pages.Add(新建页面);
}
}
其他的
{
if(CurrentPages.Contains(AssignedPage.ID))
{
ZMenu.Pages.Remove(新建页面);
}
}
}
}
调用Context.SaveChanges()时会发生此错误

编辑3:

正如你所看到的,这个问题现在得到了部分回答

谁能告诉我如何刷新ZMenu.Pages值而不导致多个被跟踪对象的错误。

发现了问题

调试后,我没有
public void AddOrUpdateCourses(ZMenu ZMenu, IEnumerable<AssignedPageData> AssignedPages)
    {
        Context.ZMenuModules.Attach(ZMenu);
        HashSet<int> CurrentPages = new HashSet<int>
        (ZMenu.Pages.Select(i => i.ID));

        foreach (var AssignedPage in AssignedPages)
        {
            ZPage newpage = Context.ZPages.Find(AssignedPage.ID);
            Context.ZPages.Attach(newpage);
            if (AssignedPage.Assigned)
            {
                if (!CurrentPages.Contains(AssignedPage.ID))
                {
                    ZMenu.Pages.Add(newpage);
                }
            }
            else
            {
                if (CurrentPages.Contains(AssignedPage.ID))
                {
                    ZMenu.Pages.Remove(newpage);
                }
            }
        }
    }