希望是一个非常简单的问题.但是我正在使用一个MVC应用程序的Code First,并且我有一个具有多对多关系的Category和ServiceType对象:
public class Category { public Category() { ServiceTypes = new HashSet<ServiceType>(); } public Guid CategoryId { get; set; } [required(ErrorMessage = "Name is required")] public string Name { get; set; } public virtual ICollection<ServiceType> ServiceTypes { get; set; } }
数据库已正确生成,并包含名为CategoryServiceTypes的链接表.我的问题是我将项目添加到我的ServiceTypes集合并调用save,虽然没有发生错误,但是没有行添加到CategoryServiceTypes.当以下代码到达SaveChanges时,category.ServiceTypes的计数为1,所以在集合中肯定有一些东西:
[HttpPost] public ActionResult Edit(Category category,Guid[] serviceTypeIds) { if (ModelState.IsValid) { // Clear existing ServiceTypes category.ServiceTypes.Clear(); // Add checked ServiceTypes foreach (Guid serviceType in serviceTypeIds) { ServiceType st = db.ServiceTypes.Find(serviceType); category.ServiceTypes.Add(st); } db.Entry(category).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(category); }
我希望我在这里做明显的错误.有任何想法吗?
谢谢.
编辑:
虽然以下回应确实是正确的答案,我以为我会添加以下最后版本的编辑帖子方法:
[HttpPost] public ActionResult Edit(Category category,Guid[] serviceTypeIds) { if (ModelState.IsValid) { // Must set to modified or adding child records does not set to modified db.Entry(category).State = EntityState.Modified; // Force loading of ServiceTypes collection due to lazy loading db.Entry(category).Collection(st => st.ServiceTypes).Load(); // Clear existing ServiceTypes category.ServiceTypes.Clear(); // Set checked ServiceTypes if (serviceTypeIds != null) { foreach (Guid serviceType in serviceTypeIds) { ServiceType st = db.ServiceTypes.Find(serviceType); category.ServiceTypes.Add(st); } } db.SaveChanges(); return RedirectToAction("Index"); } return View(category); }
注意强制加载ServiceTypes集合的行,这是需要的,因为延迟加载不包括那些子项,这意味着清除ServiceTypes集合什么都不做.
解决方法
尝试将您将类别附加到行前面的循环前面的上下文:
[HttpPost] public ActionResult Edit(Category category,Guid[] serviceTypeIds) { if (ModelState.IsValid) { // Clear existing ServiceTypes category.ServiceTypes.Clear(); db.Entry(category).State = EntityState.Modified; // category attached now,state Modified // Add checked ServiceTypes foreach (Guid serviceType in serviceTypeIds) { ServiceType st = db.ServiceTypes.Find(serviceType); // st attached now,state Unchanged category.ServiceTypes.Add(st); // EF will detect this as a change of category and create sql // to add rows to the link table when you call SaveChanges } db.SaveChanges(); return RedirectToAction("Index"); } return View(category); }
在您的代码中,EF不会注意到您已经添加了服务类型,因为当servicetypes已经在category.ServiceTypes集合中并且所有服务类型已经被附加到上下文中时,将类别附加到上下文.