我跟着这个 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值而不会导致多个对象被跟踪错误。
您是否尝试过的连接ZMenu。您可能需要确保ZMenu也被更改跟踪。根据我的经验,我需要附加链中的所有对象。 – Jim