Procedure: Query's opslaan en opnieuw gebruiken
Wanneer u een toepassing hebt die structureel vergelijkbare query's vaak uitvoert, kunt u de prestaties vaak verhogen door de query eenmalig te compileren en meerdere keren uit te voeren met verschillende parameters. Een toepassing moet bijvoorbeeld alle klanten ophalen die zich in een bepaalde stad bevinden, waarbij de stad tijdens runtime door de gebruiker in een formulier wordt opgegeven. LINQ naar SQL ondersteunt het gebruik van gecompileerde query's voor dit doel.
Notitie
Dit patroon van gebruik vertegenwoordigt het meest voorkomende gebruik voor gecompileerde query's. Andere benaderingen zijn mogelijk. Gecompileerde query's kunnen bijvoorbeeld worden opgeslagen als statische leden in een gedeeltelijke klasse die de code uitbreidt die door de ontwerper wordt gegenereerd.
Voorbeeld 1
In veel scenario's wilt u de query's mogelijk opnieuw gebruiken binnen threadgrenzen. In dergelijke gevallen is het opslaan van de gecompileerde query's in statische variabelen met name effectief. In het volgende codevoorbeeld wordt ervan uitgegaan dat een Queries
klasse is ontworpen voor het opslaan van gecompileerde query's en ervan uitgaat dat een Northwind-klasse een sterk getypte DataContextklasse vertegenwoordigt.
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
Voorbeeld 2
U kunt momenteel geen query's opslaan (in statische variabelen) die een anoniem type retourneren, omdat het type geen naam heeft die moet worden opgegeven als een algemeen argument. In het volgende voorbeeld ziet u hoe u het probleem kunt omzeilen door een type te maken dat het resultaat kan vertegenwoordigen en dit vervolgens te gebruiken als een algemeen argument.
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