クエリのリモート実行とローカル実行
クエリは、リモートで実行することも (データベース エンジンによるデータベースに対するクエリの実行)、ローカルに実行することも (LINQ to SQL によるローカル キャッシュに対するクエリの実行) できます。
リモート実行
次のクエリがあるとします。
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.
}
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
データベース内に大量の行がある場合は、小さなサブセットを処理するためにすべての行を取得するのは望ましくありません。 LINQ to SQL では、EntitySet<TEntity> クラスに IQueryable インターフェイスが実装されています。 これにより、このようなクエリをリモートで実行することが可能になります。 この方法には、次の 2 つの大きな利点があります。
不要なデータは取得されません。
多くの場合、データベース エンジンによって実行されるクエリは、データベース インデックスの効果でより効率的になります。
ローカル実行
一方、関連するエンティティ全体をローカル キャッシュに取り込むことが必要な場合もあります。 この目的から、EntitySet<TEntity> には、Load のすべてのメンバーを明示的に読み込む EntitySet<TEntity> メソッドが用意されています。
EntitySet<TEntity> が既に読み込まれている場合、それ以降のクエリはローカルに実行されます。 この方法は、次の 2 つの点で役立ちます。
データ全体をローカルで使用する必要がある場合、または複数回使用する必要がある場合に、リモート クエリおよびそれに伴う待機時間を回避できます。
エンティティ全体をシリアル化できます。
次のコードは、ローカル実行を行う方法を示しています。
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.
}
}
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
比較
この 2 種類の実行方法は、強力なオプションの組み合わせになります。つまり、大規模なコレクションではリモート実行を、小規模なコレクションまたは完全なコレクションが必要な場合はローカル実行を選択できます。 リモート実行は IQueryable を使用して実装し、ローカル実行はメモリ内の IEnumerable<T> コレクションに対して行います。 ローカル実行 (つまり IEnumerable<T>) を強制するには、「汎用 IEnumerable への型の変換」を参照してください。
順序なしのセットに対するクエリ
List<T> を実装するローカル コレクションと、リレーショナル データベース内の "順序なしのセット" に対してリモート クエリを実行するコレクションの間には、重要な違いがあることに注意してください。 インデックス値を使用するメソッドなど、List<T> のメソッドにはリストのセマンティクスが必要ですが、これは通常、順序なしのセットに対するリモート クエリからは得られません。 このため、このようなメソッドでは、ローカル実行を可能にするために暗黙的に EntitySet<TEntity> が読み込まれます。