2009-06-16 21 views
0

私は、次のコードを実行した場合、それは次のようなエラーがスローされますエンティティオブジェクトはIEntityChangeTrackerEntity Frameworkのとエンティティトラッカー問題

public void Save(Category category) 
     { 
      using(var db = new NorthwindContext()) 
      { 
       if(category.CategoryID == 0) 
       { 
        db.AddToCategorySet(category); 
       } 

       else 
       { 
        //category.RemoveTracker(); 
        db.Attach(category); 
       } 

       db.SaveChanges(); 
      } 
     } 

の複数のインスタンスによって参照することはできません

その理由は、もちろんですカテゴリは、すでにEntityChangeTrackerをカテゴリオブジェクトに添付したGetByIdメソッドから取得したインターフェイスから送信されます。エンティティトラッカーをnullに設定しようとしましたが、カテゴリオブジェクトを更新しませんでした。

protected void Btn_Update_Category_Click(object sender, EventArgs e) 
     { 
      _categoryRepository = new CategoryRepository(); 
      int categoryId = Int32.Parse(txtCategoryId.Text); 

      var category = _categoryRepository.GetById(categoryId); 

      category.CategoryName = txtUpdateCategoryName.Text; 

      _categoryRepository.Save(category); 
     } 

答えて

0

私はまだEntity Frameworkを自分自身で学習していますが、少し助けてくれるかもしれません。 Entity Frameworkを使用する場合は、さまざまなコンテキストをどのように扱うかを意識する必要があります。できるだけ多くの文脈をローカライズしようとしているようですが、

public void Save(Category category) 
{ 
    using (var db = new NorthwindContext()) 
    { 
     ... 
    } 
} 

...あなたのデータアクセス方法内です。 GetByIdメソッドで同じことをしましたか?もしそうなら、戻ったオブジェクトを切り離して、別のコンテキストで後で取り付けることができるのを覚えましたか?

public Category GetById(int categoryId) 
{ 
    using (var db = new NorthwindContext()) 
    { 
     Category category = (from c in db.Category where Category.ID == categoryId select c).First(); 
     db.Detach(category); 
    } 
} 

あなたはすでに接続コンテキストにステップしようとしていないAttachを呼び出してその方法。それは役に立ちますか?

あなたのコメントで指摘したように、項目を変更してデータベース層に保存しようとすると、項目がコンテキストから切り離されても追跡されないために問題が発生しますそれに加えられた変更のこの問題を回避するために私が考えることができるいくつかの方法がありますが、どれも完璧ではありません。

  1. アーキテクチャでサポートされている場合、SaveメソッドがGetByIdメソッドが使用するのと同じコンテキストを使用できるようにコンテキストの範囲を拡張することができます。これは、全体的な着脱の問題を完全に回避するのに役立ちますが、データレイヤーをビジネスロジックに近づけることができます。
  2. IDに基づいてアイテムの新しいインスタンスを新しいコンテキストからロードし、渡されたカテゴリに基づいてすべてのプロパティを設定して保存できます。これは実際に必要なものについて2回のデータベース往復に要し、それほどメンテナンスは難しい。
  3. コンテキスト自体を掘り下げて、カテゴリのプロパティを変更済みとしてマークできます。たとえば、

public void Save(Category category) 
{ 
    using (var db = new NorthwindContext()) 
    { 
     db.Attach(category); 
     var stateEntry = db.ObjectStateManager.GetObjectStateEntry(category); 
     foreach (var propertyName in stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(fm => fm.FieldType.Name)) { 
      stateEntry.SetModifiedProperty(propertyName); 
     } 
     db.SaveChanges(); 
    } 
} 

これは少し醜いに見えるが、全体的によりパフォーマンスとメンテナンスしなければなりません。さらに、必要に応じて、どこか拡張メソッドに投げるのに十分な汎用性を持たせることができますので、醜いコードを見たり繰り返したりする必要はありませんが、それでも機能を引き出すことはできます。

+0

ありがとうございますが、カテゴリオブジェクトがSaveメソッドになると、EntityStateはそれが変更されていないことを示します。 –

+0

良い点。私はいくつかの提案を追加して投稿を更新しました。 – StriplingWarrior

関連する問題