2012-03-28 17 views
0

最近、Entity Frameworkのレイジーロードとプロキシ生成をオフにしました。この前に、EFに新しい変更をコミットした後、オブジェクトグラフ全体を戻します。私が今やっていることは、コミット後、新しいオブジェクトを取得するためにリポジトリのFindByIdメソッドを呼び出すことです(newleyオブジェクトに戻すナビゲーションプロパティを含めています)。私の質問は、これは作成後の標準的な習慣か、クライアントが新たに作成されたオブジェクトを取得するためにサービスを再度呼び出す責任があるかどうかです。サービスのServiceおよびEntity Framework 4.1を使用している間に、新しく作成されたオブジェクトを保存して戻しますか?

保存方法:

私はちょうどオブジェクトが無効になって遅延ロードおよびプロキシの作成で作成された後、これがベストプラクティスであるかどうかを知りたい
public SomeObject Create(SomeObject someObject) 
{ 
    _repository.Add(someObject); 
    _repository.UnitOfwork.Commit() 

    //this did not exist when lazy loading and proxy generation were enabled. 
    var newObject = _repository.FindById(someObject.Id); 
    return newObject; 

    //Before we would jsut return the created object because everything was loaded. 
    //return someObject 

} 

。私は他の開発者がこれをどう扱っているか知りたいと思っています。

+0

保存してまだ手元にあるオブジェクトをロードする理由がわかりません。'FindById'が' Commit'が使っていたのと同じコンテキストを使うと、 'newObject'は' someObject'と同じオブジェクトを参照するだけで、まだコンテキストにアタッチされています。私の推測では、あなたの質問はナビゲーションプロパティの読み込みと関係がありますが、それは私には分かりません。 'FindById'は、以前の遅延ロードを置き換えると思われるすべてのナビゲーションプロパティに対して' Include'を含んでいますか? – Slauma

+0

@Slauma、あなたはIncludesとナビゲーションのプロパティについて正しいです。私はコミット後にナビゲーションプロパティをロードしたい。 – DDiVita

答えて

2

すべては がロードされていたので、作成したオブジェクトを返す前にjsutを実行します。

どういうわけか私はこれがまったく真実ではないと思います。 SaveChangesに電話した場合、遅延ロードを使用するかどうかにかかわらず、EFはナビゲーションプロパティをロードするクエリを実行しません。たとえば:

は、あなたが顧客に、データベース内のナビゲーションを参照して受注があるとし、すでに今、あなたは順序を作成、ID = 1と顧客である(遅延ロードが有効になっている):

var order = context.Orders.Create(); 
order.CustomerId = 1; 
context.Orders.Add(order); 
context.SaveChanges(); 

bool isCustomerLoaded = context.Entry(order).Reference(o => o.Customer).IsLoaded; 

isCustomerLoadedfalseになります。ただし、顧客1がすでにコンテキスト内にある場合を除き、遅延ロードを行わずにプロパティにも値が設定されます(リレーションシップフィックスアップ)。もちろん、order.Customerにアクセスするとすぐに、遅延読み込みのために読み込まれますが、それは後で起こり、SaveChangesとは関係ありません。

あなたのコードが良いアイデアであるかどうかは、返されるオブジェクトがどのように使われるか、そして消費者が期待するものによって決まります。一般的に、遅延ロードなしの遅延ロードの最も近い置換は、両方のロード戦略がナビゲーションプロパティをロードするための単一のクエリを実行するため、明示的なロードです。もちろん、コンシューマ側で追加のコードを導入してプロパティをロードする必要がありますが、遅延読み込みではプロパティを使用するときに「うまく動作します」という代わりに、プロキシオブジェクトのオーバーロードされたプロパティゲッターの背後でクエリーが発生します。明示的なロードは、次のようになります。

context.Entry(order).Reference(o => o.Customer).Load(); 
// or for collections 
context.Entry(order).Collection(o => o.OrderItems).Load(); 

あなたはあなたが初めてでナビゲーションプロパティにアクセスする場所でこれを呼び出す必要がありました。

Createメソッドから返されたオブジェクトがすべてのナビゲーションプロパティを必要とすることが事前に分かっている場合は、提案した方法で読み込むことができます。しかし、これは間違いなく、遅延ロードと比べてデータベースアクセスパターンの変化です。Eagerローディングでは、オブジェクトグラフ全体をロードするために単一のクエリが必要になりますが、これはDBに多数のJOINがあり、戻ってきた。遅延読み込みと明示的読み込みは複数のクエリを発行しますが、返されるデータは少なくても簡単なクエリです。モデルの細部を考慮せずに測定を行うことは、何が良いかを言うことは不可能です。

+0

あなたは正しいと私は急いでこのポストの種類を書いていたので、詳細の不足のために謝罪します。 EFによって作成されたプロキシのおかげで、私は関連するエンティティにアクセスすることができます。これは、私がセーブの変更後にアクセスできる理由です。ナビゲーションは、私がそれらを要求したときにのみロードされました。私はコミットまたは一般的なクエリの後に特定のエンティティを含めるためのインフラストラクチャ(私が共有する)を考え出しました。 – DDiVita

+0

コミット後に他のユーザーが(reget中に)エンティティを含むか、特定のエンティティをロードしているかどうかを知ることがより興味があります。 Reference()。Loadを使用すると、あなたが述べたようにInclude()を使用する方がパフォーマンスが向上するのだろうかと思います。 – DDiVita

+0

これは良い記事です:http://thedatafarm.com/blog/data-access/the-cost-of-eager-loading-inentity-framework/ – DDiVita

関連する問題