2012-03-01 20 views
12

Mam nadzieję, że to bardzo proste pytanie. Ale używam kod najpierw z aplikacji MVC i mam kategorię i ServiceType obiekt, który posiada wiele do wielu relacji:Entity Framework 4 Nie zapisywanie moich wielu-do-wielu wierszy

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

Baza danych została poprawnie wygenerowany i zawierający tabelę łączącą nazwie CategoryServiceTypes. Mój problem polega na tym, że dodaje elementy do mojej kolekcji ServiceTypes i zapisuję połączenia i chociaż nie ma błędu, żadne wiersze nie są dodawane do CategoryServiceTypes. Kiedy poniższy kod pobiera SaveChanges licznik na category.ServiceTypes wynosi 1, więc coś jest na pewno w kolekcji:

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

Mam nadzieję, że robię coś złego oczywiście tutaj. Jakieś pomysły?

Dzięki.

EDIT:

Chociaż poniżej odpowiedź jest rzeczywiście poprawna odpowiedź Myślałam, że należy dodać następującą ostateczną wersję metody Edycja postu:

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

Zawiadomienie linia, która wymusza ładowanie Kolekcja ServiceTypes jest potrzebna, ponieważ leniwy ładunek nie zawiera tych elementów podrzędnych, co oznacza, że ​​czyszczenie kolekcji ServiceTypes nic nie dało.

Odpowiedz

8

Spróbuj przesunąć linię gdzie przywiązują kategorię do kontekstu przed pętli:

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

w kodzie EF nie zauważyć, że zostały dodane servicetypes bo dołączyć kategorię kontekst, gdy servicetypes są już w kolekcji category.ServiceTypes, a wszystkie typy servicetes są już dołączone do kontekstu w stanie Unchanged.

+0

Dzięki Slauma, to był dokładnie problem. – Gary

+0

Mimo że teraz poprawnie zapisujesz wpisy w bazie danych, stwierdzam, że po wprowadzeniu metody Edit httppost liczba categoryServiceTypes wynosi 0, mimo że w metodzie edycji odpowiedzi zdecydowanie zawiera ona 1 zapisany typ ServiceType. Jakieś pomysły, co to powoduje? – Gary

+0

@Gary: To byłby problem z modelem MVC. Dla mnie wygląda na to, że nie ma znaczenia, czy 'category.ServiceTypes' zawiera coś, ponieważ pierwszą rzeczą, którą robisz, jest czyszczenie tej listy. Ważne jest tylko kolekcja 'Guid [] serviceTypeIds', ponieważ ładujesz ServiceType z bazy danych przy pomocy' Find' przy użyciu tych identyfikatorów, a następnie utwórz powiązanie z załadowanym obiektem. – Slauma

Powiązane problemy