Procedura: archiviare e riutilizzare le query (LINQ to SQL)
Quando si utilizza un'applicazione che esegue molte volte query strutturalmente simili, è spesso possibile migliorare le prestazioni compilando la query una volta ed eseguendola più volte con parametri diversi. Un'applicazione potrebbe ad esempio essere utilizzata per recuperare tutti i clienti di una determinata città, specificata in fase di runtime dall'utente in un modulo. In LINQ to SQL è supportato l'utilizzo di query compilate per questo scopo.
![]() |
---|
Questo modello di utilizzo rappresenta il metodo più comune di utilizzo delle query compilate.Sono tuttavia possibili altri approcci.Ad esempio, le query compilate possono essere archiviate come membri statici in una classe parziale che estende il codice generato dalla finestra di progettazione. |
Esempio
In molti scenari è possibile riutilizzare le query oltre i limiti dei thread. In questi casi l'archiviazione delle query compilate in variabili statiche è particolarmente efficace. Nell'esempio di codice riportato di seguito si presuppone una classe Queries progettata per archiviare le query compilate e una classe Northwind che rappresenta un oggetto DataContext fortemente tipizzato.
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
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));
' 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
// 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);
}
Attualmente non è possibile archiviare in variabili statiche le query che restituiscono un tipo anonimo, perché il tipo non dispone di un nome da fornire come argomento generico. Nell'esempio riportato di seguito viene descritto come risolvere questo problema creando un tipo in grado di rappresentare il risultato, quindi utilizzandolo come argomento generico.
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
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 });
}