2011-10-29 18 views
1

私はMessageというモデルを持っています。モデルには、Resourceという別のモデルのICollection ResourceSubscribersがあります。試してみるとIEntityChangeTrackerの複数のインスタンスでエンティティオブジェクトを参照できません

public void SaveMessage(List<int> subscribers) 
    { 
     Condition.Requires(model).IsNotNull(); 
     Message model = new Message(); 

     //Some assignments to initialize the model 

     ICollection<Resource> res = new List<Resource>(); 

     foreach (var item in subscribers) 
     { 
      res.Add(this.ResourceService.GetResourceById(item)); 
     } 

     model.ResourceSubscribers = res; 
     Context.Messages.Add(model); 
     Context.SaveChanges(); 
    } 

"Context.Messages.Add(model);" InvalidOperationExceptionが発生し、 "エンティティオブジェクトはIEntityChangeTrackerの複数インスタンスで参照できません"というメッセージが表示されます。

答えて

0

あなたがリソースを取得するためにGetResourceByIdに別のコンテキストを使用していますか?その場合、それらのオブジェクトはそのコンテキストに関連付けられます。 Context.Messages.Addを実行しているときは、許可されていない別のコンテキストにオブジェクトを関連付けようとします。

関連するすべての操作は、同じコンテキストを使用する必要があります。周囲に複数のコンテキストを持つことは問題を求めています。

+0

答えをありがとう。 ます。public void SaveMessage(一覧加入者) { Condition.Requires(モデル).IsNotNull(); メッセージモデル=新しいメッセージ(); //モデルを初期化する一部の割り当て ICollection res = new List (); foreachの(加入者でVAR項目) {res.Add(this.Context.Resources.Find(アイテム))。 } model.ResourceSubscribers = res; Context.Messages.Add(model); コンテキスト。変更内容を保存(); } 私のために働いた。 – dload

+0

@dload:これがあなたの問題の解決に役立つ回答であれば、チェックマークをクリックして問題を解決したものとしてマークする必要があります。 –

2

あなたはシングルトンインスタンスとしてコンテキストを使用するために任意のより良い同じコンテキストを使用している場合。

これは、クラスはインスタンスを1つだけ持っていることを確認し、これを確認し、それに

のアクセスのグローバルなポイントを提供します:http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

+0

私が過去に得た答えを確認してください: '基本的に、私は仕事の単位ごとに新鮮な文脈を作成することをお勧めします' http://stackoverflow.com/questions/14359297/execution-of-the-command-requires-an - 利用可能な接続および利用可能な接続 –

0

それは古い質問ですが、私は、私はケースに私の答えを投稿しようと思いましたそれは誰かを助ける。

ELADベンダによって述べたように、私は、でも作業パターンの単位を使用して、私のMVCコードで、これと同じ問題に出くわしました。私は自分のDbContextリソースがコントローラコールの終了時に解放されていないことを発見しました。

using (_DatabaseUow) 
    { 
     // your controller code that accesses the database here. 
    } // When this goes out of scope dispose is called. 

そして_ObdBusinessData部材がリポジトリと同様である

public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing == true) 
     { 
      _ObdDbContext.DetachAll(); 
      _ObdDbContext = null; 
      _ObdBusinessData = null; 
     } 
    } 

    ~DatabaseUnitOfWork() 
    { 
     Dispose(false); 
    } 

DatabaseUnitOfWorkクラスを配置。最後にDbContext派生クラスでDetachAll()メソッドは次のようになります。

public void DetachAll() 
    { 
     var entries = SetTestsOnlineData.Local; 
     while (entries.Count != 0) 
     { 
      TestsOnlineData tod = entries[0]; 
      Tests tro = entries[0].Tests; 
      List<TestsDtc> dtcs = entries[0].Tests.TestsDtcs.ToList(); 

      foreach (TestsDtc dtc in dtcs) 
       Detach(dtc); 
      Detach(entries[0].Tests); 
      Detach(entries[0]); 

      tro.TestsDtcs = dtcs; 
      tro.TestsOnlineData = tod; 
      tod.Tests = tro; 
     } 
    } 

    public void Detach(object entity) 
    { 
     ((IObjectContextAdapter)this).ObjectContext.Detach(entity); 
    } 

は、私は、メモリ内のすべてを切り離すために私のエンティティ/オブジェクトの特定の知識を使用していました。 TestsOnlineDataというテーブルがあります。 TestsDtcのリストにリンクしているTestsにリンクします。私のオブジェクトツリーのルートは保持されるので、これらのリンク関係は保持されますが、DbContextはデタッチされたときに他のものを解放します。

私は、これは、より汎用的にするために好きだろうが、これは働いていました。私はこれが役立つことを願っています

関連する問題