4

私の好奇心(および将来の知識)のために、Entity Framework 5は、既存のオブジェクトを参照するのではなく、新しいオブジェクトを作成するタイミングをどのように決定しますか?私はちょうど何か間違ったことをしているかもしれませんが、私が次の線に沿って何かをする場合は時々そうです:

using (TestDB db = new TestDB())
{
    var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
    if(currParent == null) {
         Parent newParent = new Parent();
         newParent.Prop = passedProp;
         currParent = newParent;
    }
    //maybe do something to currParent here
    var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
    currThing.Parent = currParent;
    db.SaveChanges();
}

EFは、データベースに新しい親(基本的にはcurrParentのコピー)を作成し、currThingのParent_ID値をそのコピーに設定します。次に、もう一度実行すると(たとえば、それらの親がすでに2つある場合)、新しい親は作成されず、代わりに最初の親にリンクされます。私はこの振る舞いを本当に理解していませんが、しばらくそれをいじった後、次のようなものがあります。

using (TestDB db = new TestDB())
{
    var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
    if(currParent == null) {
         Parent newParent = new Parent();
         newParent.Prop = passedProp;
         currParent = newParent;
    }
    //maybe do something to currParent here
    var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
    currThing.Parent = db.Parents.Where(p => p.ID == currParent.ID).First();
    db.SaveChanges();
}

問題を解決したようです。私が知っておくべきこれが起こるかもしれない理由はありますか、それとも私がその時それをしていた方法について何か奇妙なことがありましたか?申し訳ありませんが、正確なコードについて詳しく説明することはできません。しばらく前にこれに遭遇し、上記のコードで修正したため、質問する理由がわかりませんでした。より一般的には、EFは、新しいアイテムを作成するのではなく、既存のアイテムを参照するかどうかをどのように決定しますか?IDが設定されているかどうかだけに基づいていますか?ありがとう!

4

1 に答える 1

2

あなたの特定のインスタンスがあなたDBContextにそのエンティティのその特定のインスタンスを提供した場合、それはそれが表すデータベース内のどのレコードを知っており、あなたがそれに加えた変更はそのレコードに適切ですデータベース。新しいエンティティを自分でインスタンス化する場合DBContextは、データベースに挿入する必要がある新しいレコード以外のものである場合、そのレコードが正確に何であるかを伝える必要があります。

DBContext複数のインスタンスがあり、1つのインスタンスがこのエンティティを提供するが、別のインスタンスを使用してエンティティを操作および保存する特別なシナリオでは、((IObjectContextAdapter)firstDbContext).ObjectContext.Detach()このエンティティを孤立させてから、を使用((IObjectContextAdapter)secondDbContext).ObjectContext.Parents.Attach()してアタッチする必要ApplyChanges()があります(または'またそれを編集しています-これはあなたを必要とAttachします)。

他のいくつかの特別なシナリオ(オブジェクトがシリアル化されている、および/または自己追跡エンティティがある)では、正確に何をしようとしているかに応じて、いくつかの追加の手順が必要になる場合があります。


要約すると、のDBContext特定のインスタンスがエンティティの特定のインスタンスを「認識」している場合、データベース内のその特定の行に直接関連付けられているかのように動作します。

于 2013-02-04T23:57:27.130 に答える