3

EF 5.0 を使用して Web を作成していますが、コンテキストの破棄に問題があります。コンテキストを使用するときは常に using 文内にあるため、コンテキストは自動的に破棄されるはずですが、エンティティをコンテキストにアタッチしようとすると、特定の瞬間に次のエラーが発生します。

同じキーを持つオブジェクトが ObjectStateManager に既に存在します。ObjectStateManager は、同じキーを持つ複数のオブジェクトを追跡できません。

エンティティは処分されていないようです。この状況をどのように管理するのですか?エンティティを破棄するために ObjectContext を破棄する必要がありますか、またはエンティティがアタッチされているかどうかを確認する方法はありますか?

よろしく。

4

4 に答える 4

1

これを行う 1 つの方法は、アタッチする前に既存のオブジェクトをデタッチすることです。目の前にVSがないので、コードが正確でない場合はお詫び申し上げます。

var existingObject = dbContext.Users.Local
  .FirstOrDefault(x => x.id = newObject.id);

if (existingObject != null)
{
  // remove object from local cache
  dbContext.Entry(existingObject).State = EntityState.Detached;
}

dbContext.Users.Attach(newObject);

これで問題が解決しない場合は、古い方法でオブジェクトを切り離す必要があります。

  // remove object from local cache
  ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
  objectContext.Detach(existingObject);
于 2012-11-17T19:06:21.057 に答える
0

Dispose「工場出荷時の設定に戻す」という意味ではありません。これは、データベース接続などの管理されていないリソースをクリーンアップする方法です。

于 2012-11-17T22:50:51.493 に答える
0

この問題は、コンテキストを破棄するかどうかとは関係ありません。どこかに複数のコンテキストがあることとは何の関係もありません。これが問題になる場合は、「IEntityChangeTracker の複数のインスタンスでエンティティ オブジェクトを参照できません」という例外が発生します。これは、例外とはまったく異なります。

単一のコンテキストのみを使用して、例外を非常に簡単にシミュレートできます。

using (var ctx = new MyContext())
{
    var customer1 = new Customer { Id = 1 };
    var customer2 = new Customer { Id = 1 }; // a second object with the same key

    ctx.Customer.Attach(customer1);
    ctx.Customer.Attach(customer2); // your exception will occur here
}

この例外の原因となる問題は通常、より隠されています。特に、状態 (たとえば にModified) をアタッチまたは設定すると、アタッチするエンティティのオブジェクト グラフ内のすべての関連エンティティもアタッチされることに注意してください。このグラフに同じキーを持つ 2 つのオブジェクトがある場合、これらの関連するエンティティを明示的にアタッチしていなくても、同様に例外が発生します。

ただし、コードの詳細がなければ、正確な理由を見つけることは不可能です。

于 2012-11-17T23:15:09.887 に答える
0

あなたがそのようなことをするなら:

User u;
using (Entities ent = new Entities())
{
    u = ent.Users.Single(a => a.ID == 123);
}
using (Entities ent2 = new Entities())
{
    //loading the same user
    User user2 = ent2.Users.Single(a => a.ID == 123);

    //trying to attach the same object with the same key
    ent2.Attach(u);
}

次に、このエラーが発生します(このコードはテストしていません)。

編集:解決策の1つは、オブジェクトの状態を変更することです:

ent2.Attach(u);
ent2.ObjectStateManager.ChangeObjectState(u, EntityState.Modified);

別の解決策は、エンティティが既にアタッチされているかどうかを確認することです。

ObjectStateEntry state = null;
if(!ent2.ObjectStateManager.TryGetObjectStateEntry(((IEntityWithKey)u).EntityKey, out state))
{
    ent2.Attach(u);
}
于 2012-11-17T17:45:35.683 に答える