2013-03-21 14 views
9

DbContextでDatabase Firstを使用して、Linq-to-SQLからEntity Framework(4.4)に移行しています。私は、次の動作が正常であるかどうかと思いまして:アソシエーションを変更すると、外部キーのプロパティを手動で設定する必要がありますか?

using (var e = new AgendaEntities()) { 
    var store = e.Stores.First(); 
    var office = e.Offices.Create(); 
    office.Store = store; // Set association 
    Console.WriteLine(office.StoreID); // shows Guid.Empty, expected store.ID! 
} 

L2Sで、またStoreIDキーを更新してしまうエンティティにStoreの関連付けを設定します。 EFでは、これは起こっていないようです。これは、エンティティが新規であるか、コンテキストからロードされているかにかかわらずです。

SaveChangesと入力すると、正しく保存され、はoffice.IDに一致するように更新されますが、これは保存後にのみ発生するのはなぜですか?

私には何か不足しているのですか?それとも、外部キーを手動で同期させることになっていますか?


ソリューション編集: このプロパティフィックスアップと呼ばれ、生成されたプロキシによって自動的に行われるために使用されます。しかし、DbContextではこれはもはや当てはまりません。 this Connect issueによれば、これは設計によるものです。ただ遅延読み込みプロキシ(フィックスアップをしないもの) -

こんにちは、 DbContextテンプレートは、実際に変更追跡プロキシとして使用されるクラスを生成しません。変更追跡プロキシは複雑で、開発者にとって非常に混乱する可能性のあるニュアンスが多いため、この決定を下しました。 SaveChangesの前に修正が必要な場合は、myContext.ChangeTracker.DetectChangesを呼び出すことができます。 〜EFチーム

代わりにDbContext.Entry(entity)を呼び出してエンティティを同期させます。これについては、この記事「Relationships and Navigation Properties」の「FKとナビゲーションプロパティ間の変更の同期」の下に記載されています。

+0

これ以上の人はこの解決策を理解できません。このようにdbcontextを使用する人はいませんか? – danihp

+0

個人的には、アソシエーションを変更するたびに手動でキーを設定するだけです。フィックスアップは素晴らしいものでしたが、いくつかの考えの後では、POCOにはとにかくそれができると期待するのはあまり意味がありません。アソシエーションを変更する操作は、とにかく一部のドメインレイヤメソッドで抽象化する必要があります。最終的には、それは私が思っていたように邪魔になりません。 –

+0

私はdbEntityValidationsを介して、少なくとも「単純な」エンティティのエンティティをUIレイヤに公開できるようにするため、すべてのビジネスルールを持つ「盲目的な」エンティティです。私はlazyloading関連のエンティティを 'entry.related'とするが、detectChangesのアプローチを扱う。あなたのポストと解決策をありがとう。 – danihp

答えて

6

いいえ、Entity Frameworkがこれを行います。詳細についてはRelationships and Navigation Propertiesをお読みください。

ナビゲーションプロパティに新しいオブジェクトを割り当てます。次の コードは、コースとdepartmentの間の関係を作成します。 オブジェクトがコンテキストに接続されている場合、courseも がdepartment.Coursesコレクションに追加され、そしてもちろんオブジェクトの 対応する外部キープロパティはdepartmentの キープロパティの値に設定されています。

  • course.Department = department;

しかし、あなたが観察されるようにあなたがSaveChangesまたは「FKSとナビゲーションプロパティ間の変更を同期化」部分に記載された他のいずれかの操作を呼び出した後、こののみ発生上にリンクされたドキュメントの。

あなたはプロキシなしでPOCOエンティティを使用している場合は、DetectChangesメソッドは、コンテキストに関連 オブジェクトを同期するために呼び出されることを を確認する必要があります。次のAPIが自動的に DetectChanges呼び出しをトリガーすることに注意してください。

  • DbSet.Add
  • DbSet.Find
  • DbSet.Remove
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext。エントリー
  • DbChangeTrackeこれは、すべてのでが起きていない場合はDbSet

に対してLINQクエリを実行するr.Entries

  • 、私の推測では、あなたが適切ナビゲーションプロパティの外部キーとしてStoreIDを定義していないということですStore

  • +1

    私は、あなたがリンクした記事の一番下にある「FKとナビゲーションのプロパティの間の変更を同期する」で何が起きているのかを説明します。 e.Entry(office)を呼び出すと、IDが同期されます。しかし、私はプロキシが作成されていることをデバッガで見ることができるので、*動作するはずです... –

    +0

    @IliaJerebtsov ahh correct。私は最初にあなたの質問を誤解しました。私はあなたがそれが全く起こっていないと言っていると思った。 –

    +0

    ありがとう、私はそれを理解した、明らかにフィックスアップの欠如は、DbContext APIの設計によるものです。 –

    関連する問題