クエリのリモート実行とローカル実行 (LINQ to SQL)
更新 : November 2007
クエリは、リモートで実行することも (データベース エンジンによるデータベースに対するクエリの実行)、ローカルに実行することも (LINQ to SQL によるローカル キャッシュに対するクエリの実行) できます。
リモート実行
次のクエリがあるとします。
Dim db As New Northwnd("c:\northwnd.mdf")
Dim c As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = 19283).First()
Dim orders = From ord In c.Orders _
Where ord.ShippedDate.Value.Year = 1998
For Each nextOrder In orders
' Do something.
Next
Northwnd db = new Northwnd(@"northwnd.mdf");
Customer c = db.Customers.Single(x => x.CustomerID == "19283");
foreach (Order ord in
c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
// Do something.
}
データベース内に大量の行がある場合は、小さなサブセットを処理するためにすべての行を取得するのは望ましくありません。LINQ to SQL では、EntitySet<TEntity> クラスに IQueryable インターフェイスが実装されています。これにより、このようなクエリをリモートで実行することが可能になります。この方法には、次の 2 つの大きな利点があります。
不要なデータは取得されません。
多くの場合、データベース エンジンによって実行されるクエリは、データベース インデックスの効果でより効率的になります。
ローカル実行
一方、関連するエンティティ全体をローカル キャッシュに取り込むことが必要な場合もあります。この目的から、EntitySet<TEntity> には、EntitySet<TEntity> のすべてのメンバを明示的に読み込む Load メソッドが用意されています。
EntitySet<TEntity> が既に読み込まれている場合、それ以降のクエリはローカルに実行されます。この方法は、次の 2 つの点で役立ちます。
データ全体をローカルで使用する必要がある場合、または複数回使用する必要がある場合に、リモート クエリおよびそれに伴う待機時間を回避できます。
エンティティ全体をシリアル化できます。
次のコードは、ローカル実行を行う方法を示しています。
Dim db As New Northwnd("c:\northwnd.mdf")
Dim c As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = 19283).First
c.Orders.Load()
Dim orders = From ord In c.Orders _
Where ord.ShippedDate.Value.Year = 1998
For Each nextOrder In orders
' Do something.
Next
Northwnd db = new Northwnd(@"northwnd.mdf");
Customer c = db.Customers.Single(x => x.CustomerID == "19283");
c.Orders.Load();
foreach (Order ord in
c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
// Do something.
}
}
比較
この 2 種類の実行方法は、強力なオプションの組み合わせになります。つまり、大規模なコレクションではリモート実行を、小規模なコレクションまたは完全なコレクションが必要な場合はローカル実行を選択できます。リモート実行は IQueryable を使用して実装し、ローカル実行はメモリ内の IEnumerable<T> コレクションに対して行います。ローカル実行 (IEnumerable<T>) を強制的に行う方法については、「方法 : 型を汎用 IEnumerable に変換する (LINQ to SQL)」を参照してください。
順序なしのセットに対するクエリ
List<T> を実装するローカル コレクションと、リレーショナル データベース内の順序なしのセットに対してリモート クエリを実行するコレクションの間には、重要な違いがあることに注意してください。インデックス値を使用するような List<T> のメソッドにはリストのセマンティクスが必要ですが、これは通常、順序なしのセットに対するリモート クエリからは得られません。このため、このようなメソッドでは、ローカル実行を可能にするために暗黙的に EntitySet<TEntity> が読み込まれます。