Condividi tramite


Procedura: Archiviare e riutilizzare le query

Quando si dispone di un'applicazione che esegue query strutturalmente simili molte volte, è spesso possibile aumentare le prestazioni compilando la query una volta ed eseguendola più volte con parametri diversi. Ad esempio, un'applicazione potrebbe dover recuperare tutti i clienti che si trovano in una determinata città, in cui la città viene specificata in fase di esecuzione dall'utente in un modulo. LINQ to SQL supporta l'uso di query compilate a questo scopo.

Annotazioni

Questo modello di utilizzo rappresenta l'uso più comune per le query compilate. Altri approcci sono possibili. 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 1

In molti scenari è possibile riutilizzare le query attraverso i limiti del thread. In questi casi, l'archiviazione delle query compilate in variabili statiche è particolarmente efficace. Nell'esempio di codice seguente si presuppone una Queries classe progettata per archiviare query compilate e presuppone una classe Northwind che rappresenta un oggetto fortemente tipizzato DataContext.

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

Esempio 2

Non è attualmente possibile archiviare (in variabili statiche) query che restituiscono un tipo anonimo, perché il tipo non ha alcun nome da specificare come argomento generico. Nell'esempio seguente viene illustrato come risolvere il problema creando un tipo che può rappresentare il risultato e quindi usarlo come argomento generico.

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

Vedere anche