如何:存储和重复使用查询
当您的应用程序多次执行结构上相似的查询时,您通常可以通过如下方法提高性能:编译此查询一次,然后用不同的参数执行它若干次。 例如,应用程序可能需要检索位于特定城市的所有客户,其中此城市是在运行时由用户在窗体中指定的。 LINQ to SQL 支持使用已编译的查询来实现此目的。
备注
这种使用模式代表了已编译查询最常见的用途。 也可以使用其他方法。 例如,已编译查询可以存储为扩展设计器所生成代码的分部类的静态成员。
示例 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