2012-01-19 9 views
3

私はLazyローディングの動作について混乱しています。Entityフレームワーク、ToList()を呼び出すと、FKオブジェクトが自動的に読み込まれますか?

public class Supplier 
{ 
     public int ID { get; set; } 
     [Required] 
     public string FullName { get; set; } 
     public string TaxNumber { get; set; } 
     public virtual Address DeliveryAddress { get; set; } 
} 

私がブレークポイントを置くとき:

var suppliers = dbContext.Supplier.ToList(); 

私はそれを見ることができ、私はこのように、プロパティとして住所異物を持つサプライヤオブジェクトを、持っている場合たとえば

アドレス情報は、varAddressプロパティを使い切ったときにvarサプライヤなどが利用できます。使用可能です。すべてのFKオブジェクトがロードされたことを意味しますか?しかし一方で、右手のクエリのために私は、ブレークポイントでのVisual Studioからそれを見ることができ、そしてそれはそのようなものです:自身がロードするために抱き合わせではないでしょうクエリを意味

{SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[FullName] AS [FullName], 
[Extent1].[TaxNumber] AS [TaxNumber], 
[Extent1].[DeliveryAddress_ID] AS [DeliveryAddress_ID] 
FROM [dbo].[Suppliers] AS [Extent1]} 

アドレスオブジェクトはまったくですか?

誰がFKオブジェクトをロードしていますか? ToList()またはVSデバッガ?

レイジーローディングであるかどうかを確認する方法に関するその他の提案はありますか?

注:これで、Lazyローディングは2つのToListコール、1つはレイジーローディング、もう1つはレイジーローディングで動作することが確認されました。誰かが、FKプロパティのために別のクエリを読み込み中に遅延が発生したときに、どの時点で何を知る方法を教えてもらえますか?

+0

DeliveryAddressが既に読み込まれているかどうかはどうですか?データベースに1つのクエリしか送信されていないと確信していますか? SQLプロファイラを起動して、どのクエリがdbに送信されるかを正確に確認できます。 – danludwig

+0

こんにちは、私はどのようにSQLプロファイラを起動できますか? SQL Server 2008 R2を使用していますが、SQLプロファイラのメニューが表示されないようです。私は見ることができます:インポートとエクスポート、サーバー管理スタジオ、構成ツール、統合サービス? –

答えて

6

VSデバッガは関連オブジェクトを読み込み、質問に表示されているものではなく、2番目のSQLクエリで発生します。デバッガでアドレスオブジェクトにドリルインすると、デバッガはオブジェクトのプロパティにアクセスしてその値を表示します。このオブジェクトにアクセスすると、遅延読み込みと2番目のSQLクエリがトリガされます。

編集

親オブジェクトは、あなたのSupplierタイプが、Supplierから派生したクラス(「プロキシ」)ではないので、これは動作します。この派生クラスは、実行時に動的に作成され、暗黙の自動生成された名前を持っています(このクラス名はデバッガに表示されます)。この動的クラスは基底と同じプロパティを持ちますSupplierしかし、それはDeliveryAddressプロパティをオーバーロードしています。 (そのため、これらのナビゲーションプロパティはvirtualでなければなりません。それ以外の場合、オーバーロードは不可能です)。クエリは、サプライヤクエリで既に取得されたFK列値を使用し、この値でアドレスを取得します。

supplier.DeliveryAddressでプロパティにアクセスするときに呼び出されるオーバーロードされたDeliveryAddressプロパティの新しいゲッターには、実行時にSQLクエリを実行してデータベースから関連オブジェクトをロードするコードが含まれています。派生したプロキシクラスには、様々な追加の内部メンバ、特にコンテキスト/データベース接続(クエリを実行できるようにする)と、既にナビゲーションプロパティをロードしたプロキシオブジェクトを示すフラグが保持されています。もう一度DeliveryAddressにアクセスすると、2番目の冗長クエリは実行されません。

これは、POCOでの遅延読み込みの仕組みを簡単に示しています。

+0

@サラマ、追加の説明をいただきありがとうございます、元の回答自体は良いですが、明白なことを言っています。 DeliveryAddressプロパティのクエリがいつ送信されたかを知る方法を提案してください。 SQLプロファイラの問題は、最初にインストールする必要があるようです。 –

+0

@pstar:クエリは、VSデバッガオブジェクトツリーの+ノードをクリックしてサプライヤの配信アドレスにドリルダウンすると送信されます。送信されるクエリは、 'SELECT * FROM AdressTable WHERE AddressId = DeliveryAddress_ID'のようなものです。 – Slauma

+0

@Salauma、私が見たいのは、FK Objectsのfire in actionです。私は、FKプロパティにアクセスしない限り、DeliveryAddressのクエリが起動しないことを確認していましたが、確認できませんでした。 –

関連する問題