2012-08-30 58 views
0

我跟着这个 Saving Many to Many relationship data on MVC Create viewEF CodeFirst多对多更新(MVC4)

此工程将我的多对多值。

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

我的场景是...

我有菜单和页面。

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

我将页面完美地添加到相关菜单中,但是在编辑时,即使我调用Menu.Pages.Clear(),每次都会得到相同的值。 Context.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); 
    } 

PAGEID是页面模块(菜单)被定位到,ActivePosition是模块位置它处于,OldAP是它更新之前WAS中的位置。 事情是用'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 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; 
      } 
     } 
    } 

我已禁用模块位置保护(每个模块位置1个模块),以停止从一个潜在的问题,而这并没有解决它,只是因为你想知道为什么我有一小段代码被注释掉了。

我调试了这个,当调用Commit()方法时,ZMenu实体具有正确的页面,但在此之后,页面列表被恢复为编辑之前的状态。在创建时工作。

任何人有任何线索?

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

编辑:

这里的视图模型的问题...

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

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

    public MenuViewModel() 
    { 

    } 
} 

编辑2:

由于下面的评论,有的继续工作,代码如下内容,在似乎是问题的地方,我现在遇到了一个错误,但我在黑暗中如何解决错误。

存储更新,插入或删除语句影响了意外的行数(0)。自实体加载后,实体可能已被修改或删除。刷新ObjectStateManager条目。

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

错误时Context.SaveChanges()被调用发生的情况。

编辑3:

正如你可以看到这部分回答了现在。

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

+0

您是否尝试过的连接ZMenu。您可能需要确保ZMenu也被更改跟踪。根据我的经验,我需要附加链中的所有对象。 – Jim

回答

0

发现问题。

经过调试,我注意到ZMenu在列表中根本没有页面,即使它有一个,即使编辑不起作用。所以这是错误的。 (在编辑之前)。

因此,我使用传递给HttpPost编辑动作的Model的ID从Context中“查找”ZMenu,并在整个过程中使用它,而不是我以前的“ViewModel.ZMenu”。

这使ZMenu拥有它应该拥有的1页,这必须解决程序中的所有问题并使编辑成功,我非常高兴,因为这已经让我烦恼了很多年。

+0

实际上,它现在不编辑任何接受页面,但我相信这是一个微不足道的修复。我会及时向大家发布。 – GTWelsh

+0

请参阅原始问题的编辑3。 – GTWelsh

0

我写了详细列明了一些博客文章如何创建/更新/在许多删除记录的许多场景使用EF Code First。还有一个完整的解决方案附加到帖子,所以希望你或其他人阅读这篇文章会发现它有用。这是第三次,也是最后一部分:

Saving many to many data in MVC4