遅延読み込みと即時読み込み (LINQ to SQL)
更新 : November 2007
オブジェクトに対してクエリを実行すると、要求したオブジェクトだけが実際に取得されます。関連オブジェクトが自動で同時に取得されることはありません。詳細については、「リレーションシップを介したクエリの実行 (LINQ to SQL)」を参照してください。ただし、関連オブジェクトにアクセスしようとすると、それらを取得する要求が生成されるため、関連オブジェクトがまだ読み込まれていない状態を識別することはできません。
たとえば、特定の注文のセットを取得するクエリを実行し、ときおり特定の顧客に電子メール通知を送信しようとしているとします。最初から注文ごとにすべての顧客データを取得する必要はありません。遅延読み込みを使用すると、関連情報が実際に必要になるまで、その情報の取得を遅らせることができます。次に例を示します。
Dim db As New Northwnd("c:\northwnd.mdf")
Dim notificationQuery = _
From ord In db.Orders _
Where ord.ShipVia = 3 _
Select ord
For Each ordObj As Order In notificationQuery
If ordObj.Freight > 200 Then
SendCustomerNotification(ordObj.Customer)
ProcessOrder(ordObj)
End If
Next
Northwnd db = new Northwnd(@"northwnd.mdf");
IQueryable<Order> notificationQuery =
from ord in db.Orders
where ord.ShipVia == 3
select ord;
foreach (Order ordObj in notificationQuery)
{
if (ordObj.Freight > 200)
SendCustomerNotification(ordObj.Customer);
ProcessOrder(ordObj);
}
}
その反対も同様です。顧客データと注文データを同時に表示する必要のあるアプリケーションがあるとします。両方のデータが必要であることがわかっています。このアプリケーションでは、結果を取得するのと同時に、各顧客の注文情報が必要になります。すべての顧客について注文を照会する個別のクエリを発行するのは適切ではありません。ここで必要なのは、注文データと顧客データを同時に収集することです。
Dim db As New Northwnd("c:\northwnd.mdf")
db.DeferredLoadingEnabled = False
Dim custQuery = _
From cust In db.Customers _
Where cust.City = "London" _
Select cust
For Each custObj As Customer In custQuery
For Each ordObj As Order In custObj.Orders
ProcessCustomerOrder(ordObj)
Next
Next
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
db.DeferredLoadingEnabled = false;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach (Customer custObj in custQuery)
{
foreach (Order ordObj in custObj.Orders)
{
ProcessCustomerOrder(ordObj);
}
}
1 つのクエリでクロス積によって顧客データと注文データを結合し、すべての関連データを大きな 1 つの投影として取得することもできます。ただし、このような結果はエンティティではありません (詳細については、「LINQ to SQL オブジェクト モデル」を参照してください)。エンティティとは、識別子を持ち、変更が可能なオブジェクトですが、これらの結果は投影であり、変更や永続化はできません。さらに、平坦な結合出力では、注文ごとに各顧客が繰り返し現れるため、余分なデータが大量に取得されることになります。
ここで必要なのは、関連オブジェクトのセットを同時に取得することです。このセットは、目的の用途に必要十分なデータだけを取得できるように、グラフ上に線引きされた区画に相当します。この目的から、LINQ to SQL では、オブジェクト モデルの特定の領域の即時読み込みを行う DataLoadOptions が用意されています。次のメソッドがあります。
LoadWith メソッド。メイン ターゲットに関連するデータを即時に読み込みます。
AssociateWith メソッド。特定のリレーションシップに対して取得されるオブジェクトにフィルタを適用します。