方法: クエリを格納および再利用する
同じ構造のクエリを何回も実行するアプリケーションでは、1 回コンパイルしたクエリを、パラメーターを変えて何回も実行する方が、多くの場合にパフォーマンスを向上できます。 たとえば、特定の市に住むすべての顧客を取得するアプリケーションで、ユーザーが、対象の市を実行時にフォームで指定するとします。 LINQ to SQL では、この目的で、"コンパイル済みクエリ" の使用がサポートされています。
Note
コンパイル済みクエリは、このパターンの使用法が最も一般的です。 その他にも方法は考えられます。 たとえば、デザイナーによって生成されたコードを継承した部分クラスの静的メンバーとしてコンパイル済みクエリを格納するなどです。
例 1
スレッド境界を越えてクエリを再利用することが必要となる場合もよくあります。 その場合には、コンパイル済みクエリを静的変数に格納することは特に有効です。 次のコード例では、Queries
クラスはコンパイル済みクエリを格納するためのクラスで、厳密に型指定された DataContext を表す Northwind クラスを使用することを想定しています。
public static Func<Northwnd, string, IQueryable<Customer>>
CustomersByCity =
CompiledQuery.Compile((Northwnd db, string city) =>
from c in db.Customers where c.City == city select c);
public static Func<Northwnd, string, IQueryable<Customer>>
CustomersById = CompiledQuery.Compile((Northwnd db,
string id) => db.Customers.Where(c => c.CustomerID == id));
Class Queries
Public Shared CustomersByCity As _
Func(Of Northwnd, String, IQueryable(Of Customer)) = _
CompiledQuery.Compile(Function(db As Northwnd, _
city As String) _
From c In db.Customers Where c.City = city Select c)
Public Shared CustomersById As _
Func(Of Northwnd, String, IQueryable(Of Customer)) = _
CompiledQuery.Compile(Function(db As Northwnd, _
id As String) _
db.Customers.Where(Function(c) c.CustomerID = id))
End Class
// The following example invokes such a compiled query in the main
// program.
public IEnumerable<Customer> GetCustomersByCity(string city)
{
var myDb = GetNorthwind();
return Queries.CustomersByCity(myDb, city);
}
' The following example invokes such a compiled query in the main
' program
Public Function GetCustomersByCity(ByVal city As String) As _
IEnumerable(Of Customer)
Dim myDb = GetNorthwind()
Return Queries.CustomersByCity(myDb, city)
End Function
例 2
現時点では、"匿名型" を返すクエリを (静的変数に) 格納することはできません。型には汎用引数として指定する名前がないからです。 この問題を回避する方法を次の例に示します。結果を表すことのできる型を作成し、それを汎用引数として使用しています。
class SimpleCustomer
{
public string ContactName { get; set; }
}
class Queries2
{
public static Func<Northwnd, string, IEnumerable<SimpleCustomer>> CustomersByCity =
CompiledQuery.Compile<Northwnd, string, IEnumerable<SimpleCustomer>>(
(Northwnd db, string city) =>
from c in db.Customers
where c.City == city
select new SimpleCustomer { ContactName = c.ContactName });
}
Class SimpleCustomer
Private _ContactName As String
Public Property ContactName() As String
Get
Return _ContactName
End Get
Set(ByVal value As String)
_ContactName = value
End Set
End Property
End Class
Class Queries2
Public Shared CustomersByCity As Func(Of Northwnd, String, IEnumerable(Of SimpleCustomer)) = _
CompiledQuery.Compile(Of Northwnd, String, IEnumerable(Of SimpleCustomer))( _
Function(db As Northwnd, city As String) _
From c In db.Customers _
Where c.City = city _
Select New SimpleCustomer With {.ContactName = c.ContactName})
End Class