Надеюсь, это очень простой вопрос. Но я использую Code First с приложением MVC, и у меня есть объект 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 и сохраняю вызов, и, хотя ошибок не возникает, строки в 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);
}
Надеюсь, я делаю здесь что-то явно неправильное. Есть идеи?
Спасибо.
РЕДАКТИРОВАТЬ:
Хотя приведенный ниже ответ действительно является правильным ответом, я подумал, что добавлю следующую окончательную версию метода Edit post:
[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 ничего не дала.