2012-01-03 14 views
2

私のモデルでは、カテゴリと製品の2つのクラスがあります。それらの間には多くの関係があります。私はEntity Frameworkでコードの最初のアプローチを使用しています。 カテゴリと商品のマッピングを編集する機能を作ろうとしていますが、エラーが発生します。オブジェクトコンテキストからのエンティティのデタッチ

IEntityChangeTrackerの複数のインスタンスでエンティティオブジェクトを参照できません。

エンティティフレームワークで接続を閉じた後でもエンティティが追跡されていることがわかりました。
ObjectContextからエンティティを手動で切り離さなければならないと思いますが、私の解決策は動作しません。これは私のコントローラコードです

public ActionResult Edit(int id) 
    { 
     Product product = db.Products.Find(id); 
     ViewData["categories"] = _categories.GetAllCategories(); 
     ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Name", product.CompanyID); 
     return View(product); 
    } 

    [HttpPost] 
    public ActionResult Edit(FormCollection collection, Product product) 
    { 
     if (ModelState.IsValid) 
     { 
      _product.UpdateProduct(product); 
      _product.EditMappingProductCategories(collection, product.ProductID); 
      return RedirectToAction("ProductsList"); 
     } 
     ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Name", product.CompanyID); 
     ViewData["categories"] = _categories.GetAllCategories(); 
     return View(product); 
    } 

サービスレイヤからの私の機能です。フォームcollectonから新しいカテゴリを取得し、結果に応じて商品を編集します。

public void EditMappingProductCategories(FormCollection collection , int pro) 
    { 
     using (EFDbContext context = new EFDbContext()) 
     { 
      List<Category> list = new List<Category>(); 
      Product product = context.Products.Single(m => m.ProductID == pro); 
      foreach (var item in collection.AllKeys) 
      { 
       if(collection[item].Contains("true")) 
        list.Add(context.Categories.Find(Convert.ToInt32(item))); 
      } 
      //Check if produkt contains marked category in formCollection 
      foreach (var item in list) 
      { 
       if (product.Categories.Contains(item)) 
       { 
        product.Categories.Add(item); 
        context.Entry(item).State = EntityState.Detached; 
       } 
      } 
      context.SaveChanges(); 
      //Check if product contains categories which are not marked in formCollection 
      foreach (var item in product.Categories) 
      { 
       if (list.Contains(item)) 
        product.Categories.Remove(item); 
      } 
      context.SaveChanges(); 
      UpdateProduct(product); 
     } 
    } 
    public void UpdateProduct(Product product) 
    { 
     using (EFDbContext context = new EFDbContext()) 
     { 
      context.Entry(product).State = EntityState.Modified; 
      context.SaveChanges(); 
      context.Entry(product).State = EntityState.Detached; 
     } 
    } 

問題は、どのエンティティがまだトラッキングしているのかわかりません。それをチェックするケースはありますか?デバッグモードまたはsth else?


ありがとうございました。私はこの機能を知らなかった。私はこの変更を加え、エラーは消えましたが、私は他の問題があります。私は更新関数の文脈に商品を添付しましたが、私のカテゴリは更新されませんでした。私は手動で変更したすべてのカテゴリの状態を設定し、saveChanges()関数の前にデバッガで見たとき、 カテゴリと商品のマッピングは私のデータベースでは更新されませんでした。 更新関数のコード

public void UpdateProduct(Product product) 
     { 
      using (EFDbContext context = new EFDbContext()) 
      { 
       context.Products.Attach(product); 
       if (product.Categories != null) 
       { 
        foreach (var item in product.Categories) 
        { 
         context.Entry(item).State = EntityState.Modified; 
        } 
       } 
       context.Entry(product).State = EntityState.Modified; 

       context.SaveChanges(); 
      } 
     } 
+0

まだ問題がある場合は、この問題を参照する別の質問をすることができます(この質問の範囲外) –

答えて

9

あなたはusing (EFDbContext context = new EFDbContext)を持つたびに、エンティティがそのコンテキストに特異的に接続されているので、あなたは、このエラーを得ている理由です。あるコンテキストからエンティティを読み込んで別のコンテキストにエンティティを追加しようとすると、EFが複数のコンテキストでエンティティを追跡できないというエラーが発生します。あなたが文脈の外に実体を読んでいるとき

これを試してみてください:

context.Products.AsNoTracking().Single(m => m.ProductID == pro); 

AsNoTracking()を呼び出すことによって、あなたはentitiyは、任意のコンテキストに接続されていない返されていることを確認します。更新/保存操作中に別のコンテキストに接続することができます。

+0

ありがとうございます。これはEF 6.1での簡単な実装です。 – callisto

関連する問題