web-dev-qa-db-ja.com

Entity Framework Code First-DbContextにはDetach()メソッドはありません

ObjectContextのようにDbContextオブジェクトにDetachメソッドがないのはなぜかと思っています。この省略は意図的なものであると推測できますが、その理由を理解するのは困難です。エンティティをデタッチおよび再アタッチできる必要があります(たとえば、ASP.NETプロジェクトでキャッシュに入れるため)。ただし、エンティティをデタッチできないため、前のコンテキストに関連付けられたエンティティをアタッチしようとすると、「エンティティオブジェクトをIEntityChangeTrackerの複数のインスタンスで参照できません」という例外が発生します。

ここでのガイダンスは何ですか?何か不足していますか?

62
Brian Sullivan

この質問につまずくかもしれない人々のために、CTP5の時点で、あなたは今書く必要があります

((IObjectContextAdapter)context).ObjectContext

objectContextに到達するため。

85
Joakim

DbContextは内部でObjectContextを使用し、EFチームはこれをprotectedプロパティとして使用できるようにします。これは、低レベルのAPIにドロップダウンする必要がある場合に使用します。派生DbContextから必要な機能を公開します。

public class YourContext : DbContext 
{
    public void Detach(object entity) 
    {
        ObjectContext.Detach(entity);            
    }
}

次に、コントローラーからこのメソッドを呼び出して、エンティティをデタッチできます。

あるいは、よりリッチなAPIを持つように変更することもできます。

public class YourContext : DbContext
{
    public void ChangeObjectState(object entity, EntityState entityState)
    {
        ObjectContext.ObjectStateManager.ChangeObjectState(entity, entityState);
    }
}

メタデータからDbContextがどのように見えるかを次に示します。

public class DbContext : IDisposable 
{      
    protected System.Data.Objects.ObjectContext ObjectContext { get; }
    ...
}
37
Morteza Manavi

EF:CF 4.1 RC1およびEF:CF 4.1 RTWには、同じ明示的に実装されたIObjectContextAdapterがあります。

_public static class DbContextExtensions
{
    public static void Detach(this System.Data.Entity.DbContext context, object entity)
    {
         ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.Detach(entity);
    }
}
_

Microsoftは「Detachは高度な技術であり、隠すべきだ」と決定しました。私がこれを発明した人は撃たれるべきです-新しいエンティティを追加すると、dbに変更をコミットせずにそれを削除するのが難しいためです(DbEntityEntryで操作できますが、それは別の話です)。

4年後の編集:

EF6(iはどういうわけかEF5 :))では、detach()はもう必要ありません。新しく追加されたエントリを削除してもEF4のように_delete from [table] where [Id] = 0_が生成されないため、単に呼び出すことができますmySet.Remove(myFreshlyCreatedAndAddedEntity)とすべてが問題ありません。

16
Jan 'splite' K.

通常、プロパティを使用して基本クラス(DbContextから継承)を拡張します。

public class MyDbContext : DbContext
{
    public ObjectContext ThisObjectContext
    {
        get
        {
            return ((IObjectContextAdapter)this).ObjectContext;
        }
    }
}

後で、このプロパティをさまざまな便利なものに使用できます... Detachなど:)

7
Stefan Michev