2012-03-01 14 views
12

うまくいけば、非常に単純な質問です。しかし、私はMVCアプリでコードファーストを使用していると私は、多くの関係に多くを持っているカテゴリーとサービス種別のオブジェクトがあります。Entity Framework 4多対多の行を保存しない

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に行が追加されません。以下のコードはcategory.ServiceTypesにカウントのSaveChangesするために取得すると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を追加したことに気付かないあなたのコードEFで

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

答えて

8

することで、ループの前のコンテキストにカテゴリを添付線を移動してみてくださいservicetypeがすでにcategory.ServiceTypesコレクション内にあり、すべてのservicetypeが状態Unchangedのコンテキストに既に添付されている場合のコンテキスト。

+0

ありがとうスラマ、それはまさに問題でした。 – Gary

+0

答えがデータベースに正しく保存されるようになりましたが、Edit httppostメソッドを入力すると、category.ServiceTypesの数は0になりました。何が原因なの? – Gary

+0

@Gary:これはMVCモデルバインダーの問題です。私にとって、 'category.ServiceTypes'に何かが含まれているのは本当に問題ではないようです。あなたがやっている最初のことは、とにかくそのリストをクリアしているからです。重要なのは 'Guid [] serviceTypeIds'コレクションだけです。これらのIDを使用してDBからServiceTypeを' Find'でロードしてから、ロードされたエンティティとの関連付けを作成するからです。 – Slauma

関連する問題