Надеюсь, очень простой вопрос. Но я использую 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 и вызываю 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);
}
Я надеюсь, что я делаю что-то явно не так здесь. Есть идеи?
Спасибо.
EDIT:
Хотя приведенный ниже ответ действительно является правильным ответом, я подумал, что добавлю следующую окончательную версию метода редактирования сообщения:
[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 ничего не делала.