web-dev-qa-db-ja.com

エンティティがdbContextにアタッチされているかどうかを確認する最も合理的な方法は何ですか?

エンティティをコンテキストにアタッチしようとすると、例外が発生します

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

これは予想される動作です。

しかし、ObjectStateManagerがそれをどのように知っているのか知りたいですか?前に自分でこのチェックをしたい

55
maxlego

DbContext APIを使用している場合(ef-code-firstに言及した場合)、単純に使用できます:

context.YourEntities.Local.Any(e => e.Id == id);

またはより複雑

context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id);

ObjectContext APIの場合、次を使用できます。

context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)
                          .Where(e => !e.IsRelationship)
                          .Select(e => e.Entity)
                          .OfType<YourEntity>()
                          .Any(x => x.Id == id);
75
Ladislav Mrnka

オブジェクトが既にアタッチされているかどうかを心配せずにコンテキストからオブジェクトを取得するための拡張メソッドは次のとおりです。

public static T GetLocalOrAttach<T>(this DbSet<T> collection, Func<T, bool> searchLocalQuery, Func<T> getAttachItem) where T : class
{
    T localEntity = collection.Local.FirstOrDefault(searchLocalQuery);

    if (localEntity == null)
    {
        localEntity = getAttachItem();
        collection.Attach(localEntity);
    }

    return localEntity;
}

ただ電話する:

UserProfile user = dbContext.UserProfiles.GetLocalOrAttach<UserProfile>(u => u.UserId == userId, () => new UserProfile { UserId = userId });
13
David Sherret

小切手

entity.EntityState == System.Data.EntityState.Detached

取り付ける前に

5
Kaido

コンテキストで変更の追跡が無効になっている場合、ObjectStateManagerまたはChangeTrackerを要求すると、オブジェクトがObjectContextにないことを返す場合があることに注意してください実際に既に存在している場合。したがって、そのようなオブジェクトを添付しようとすると、例外が発生します。

_context.Set<T>.Local.Any(e => e.Id == id);
_

変更追跡が無効になっている場合、イベントが機能します。

オブジェクトのタイプがわからない場合は、さまざまなアプローチがあります。リフレクションまたはこのような他の手法を使用してメソッドを定義しますint GetIdOf(object entity){...}

または、次のようにクラスで使用されるインターフェイスを定義します

_public interface IMyEntity
{
    int Id{get;set;}
}
_

このように使用します:

_context.Set(e.GetType()).Local.Cast<IMyEntity>().Any(e => e.Id == id);
_
3
Dubbs777

「Any」拡張メソッドを使用してdbContextを照会できます。

bool alreadyInDB = dbContext.Entity.Where(a=>a.ID==myEntity.id).Any();
0
Bongo Sharp