Query in LINQ to DataSetQueries in LINQ to DataSet

Una query è un'espressione che recupera dati da un'origine dati.A query is an expression that retrieves data from a data source. Le query sono in genere espresse in un linguaggio di query specializzato, ad esempio SQL per i database relazionali e XQuery per XML.Queries are usually expressed in a specialized query language, such as SQL for relational databases and XQuery for XML. Gli sviluppatori hanno dovuto pertanto imparare un nuovo linguaggio di query per ogni tipo di origine dati o formato dati usato per le query.Therefore, developers have had to learn a new query language for each type of data source or data format that they query. LINQ (Language-Integrated Query)Language-Integrated Query (LINQ) offre un modello più semplice e coerente per l'uso dei dati con tutti i vari tipi di origini e formati dati. offers a simpler, consistent model for working with data across various kinds of data sources and formats. In una query LINQLINQ vengono sempre usati oggetti di programmazione.In a LINQLINQ query, you always work with programming objects.

Un'operazione di query LINQLINQ comporta tre azioni: recupero dell'origine o delle origini dati, creazione della query ed esecuzione della query.A LINQLINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.

Per eseguire query su origini dati che implementano l'interfaccia generica IEnumerable<T> è possibile usare LINQLINQ.Data sources that implement the IEnumerable<T> generic interface can be queried through LINQLINQ. La chiamata AsEnumerable su un DataTable restituisce un oggetto che implementa l'interfaccia generica IEnumerable<T> interfaccia, che funge da origine dati per LINQ to DataSetLINQ to DataSet query.Calling AsEnumerable on a DataTable returns an object which implements the generic IEnumerable<T> interface, which serves as the data source for LINQ to DataSetLINQ to DataSet queries.

Nella query è necessario specificare esattamente le informazioni che si desidera recuperare dall'origine dati.In the query, you specify exactly the information that you want to retrieve from the data source. Una query può inoltre specificare in che modo ordinare, raggruppare e formattare le informazioni prima che vengano restituite.A query can also specify how that information should be sorted, grouped, and shaped before it is returned. In LINQLINQ le query vengono archiviate nelle variabili.In LINQLINQ, a query is stored in a variable. Se la query è progettata per restituire una sequenza di valori, la variabile di query stessa deve essere un tipo enumerabile.If the query is designed to return a sequence of values, the query variable itself must be a enumerable type. La variabile di query non esegue azioni né restituisce dati. Viene solo usata per archiviare le informazioni sulla query.This query variable takes no action and returns no data; it only stores the query information. Dopo aver creato una query è necessario eseguirla per recuperare eventuali dati.After you create a query you must execute that query to retrieve any data.

In una query che restituisce una sequenza di valori, la variabile di query stessa non contiene mai i risultati della query ma viene usata solo per l'archiviazione dei comandi della query.In a query that returns a sequence of values, the query variable itself never holds the query results and only stores the query commands. L'esecuzione della query viene posticipata finché non viene eseguita un'iterazione della variabile di query in un ciclo foreach o For Each.Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop. Si tratta di esecuzione posticipata; ovvero, query viene eseguita qualche tempo dopo la query viene costruita.This is called deferred execution; that is, query execution occurs some time after the query is constructed. È quindi possibile eseguire una query il numero di volte desiderato.This means that you can execute a query as often as you want to. Tale caratteristica è utile, ad esempio, quando si dispone di un database che viene aggiornato da altre applicazioni.This is useful when, for example, you have a database that is being updated by other applications. Nell'applicazione è possibile creare una query per recuperare le informazioni più recenti ed eseguire ripetutamente la query che restituisce ogni volta le informazioni aggiornate.In your application, you can create a query to retrieve the latest information and repeatedly execute the query, returning the updated information every time.

A differenza delle query posticipate che restituiscono una sequenza di valori, le query che restituiscono un valore singleton vengono eseguite immediatamente.In contrast to deferred queries, which return a sequence of values, queries that return a singleton value are executed immediately. Alcuni esempi di query singleton sono Count, Max, Average e First.Some examples of singleton queries are Count, Max, Average, and First. Tali query vengono eseguite immediatamente perché i risultati restituiti sono necessari per calcolare il risultato singleton.These execute immediately because the query results are required to calculate the singleton result. Ad esempio, per individuare la media dei risultati della query, è necessario eseguire la query in modo che per la funzione di calcolo della media siano disponibili i dati di input.For example, in order to find the average of the query results the query must be executed so that the averaging function has input data to work with. È inoltre possibile usare i metodi ToList o ToArray su una query per forzare l'esecuzione immediata di una query che non restituisce un valore singleton.You can also use the ToList or ToArray methods on a query to force immediate execution of a query that does not produce a singleton value. Queste tecniche per forzare l'esecuzione immediata possono essere utili quando si desidera memorizzare nella cache i risultati di una query.These techniques to force immediate execution can be useful when you want to cache the results of a query. Per ulteriori informazioni sull'esecuzione di query posticipata e immediata, vedere Introduzione a LINQ.For more information about deferred and immediate query execution, see Getting Started with LINQ.

QueryQueries

LINQ to DataSetLINQ to DataSet è possibile formulare query in due diverse sintassi: espressione sintassi delle query e sintassi di query basate su metodo. queries can be formulated in two different syntaxes: query expression syntax and method-based query syntax.

Sintassi delle espressioni di queryQuery Expression Syntax

Le espressioni di query vengono scritte in una sintassi di query dichiarativa.Query expressions are a declarative query syntax. Questa sintassi consente a un sviluppatore di scrivere query in C# o Visual Basic in un formato simile a quello di SQL.This syntax enables a developer to write queries in C# or Visual Basic in a format similar to SQL. Tramite la sintassi delle espressioni di query è possibile eseguire anche complesse operazioni di filtro, ordinamento e raggruppamento sulle origini dati usando una quantità minima di codice.By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code. Per ulteriori informazioni, vedere espressioni di Query LINQ e operazioni di Query di base (Visual Basic).For more information, see LINQ Query Expressions and Basic Query Operations (Visual Basic).

La sintassi delle espressioni di query rappresenta una novità di C# 3.0 e Visual Basic 2008Visual Basic 2008.Query expression syntax is new in C# 3.0 and Visual Basic 2008Visual Basic 2008. Tuttavia, .NET Framework.NET Framework Common Language Runtime (CLR) non è in grado di leggere da solo la sintassi delle espressioni di query.However, the .NET Framework.NET Framework common language runtime (CLR) cannot read the query expression syntax itself. Pertanto, in fase di compilazione, le espressioni di query vengono convertite in chiamate al metodo in modo da poter essere usate da CLR.Therefore, at compile time, query expressions are translated to something that the CLR does understand: method calls. Questi metodi vengono definiti il operatori di query standard.These methods are referred to as the standard query operators. Gli sviluppatori possono scegliere di chiamare direttamente questi metodi usando la relativa sintassi, anziché usare la sintassi delle query.As a developer, you have the option of calling them directly by using method syntax, instead of using query syntax. Per altre informazioni, vedere Sintassi di query e sintassi di metodi in LINQ.For more information, see Query Syntax and Method Syntax in LINQ. Per ulteriori informazioni su come usare gli operatori query standard, vedere NOT IN BUILD: Guida per programmatori LINQ generale.For more information about how to use the standard query operators, see NOT IN BUILD: LINQ General Programming Guide.

Nell'esempio seguente viene usato Select per restituire tutte le righe della tabella Product e visualizzare i nomi di prodotto.The following example uses Select to return all the rows from Product table and display the product names.

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> query =
    from product in products.AsEnumerable()
    select product;

Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
    Console.WriteLine(p.Field<string>("Name"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim products As DataTable = ds.Tables("Product")

Dim query = From product In products.AsEnumerable() _
            Select product
Console.WriteLine("Product Names:")
For Each p In query
    Console.WriteLine(p.Field(Of String)("Name"))
Next

Sintassi delle query basate su metodoMethod-Based Query Syntax

Per formulare query LINQ to DataSetLINQ to DataSet, è inoltre possibile usare query basate su metodo.The other way to formulate LINQ to DataSetLINQ to DataSet queries is by using method-based queries. La sintassi delle query basate su metodo è costituita da una sequenza di chiamate dirette del metodo ai metodi dell'operatore LINQLINQ, in cui come parametri vengono passate espressioni lambda.The method-based query syntax is a sequence of direct method calls to LINQLINQ operator methods, passing lambda expressions as the parameters. Per altre informazioni, vedere Espressioni lambda.For more information, see Lambda Expressions.

In questo esempio viene usato Select per restituire tutte le righe di Product e visualizzare i nomi di prodotto.This example uses Select to return all the rows from Product and display the product names.

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable products = ds.Tables["Product"];

var query = products.AsEnumerable().
    Select(product => new
    {
        ProductName = product.Field<string>("Name"),
        ProductNumber = product.Field<string>("ProductNumber"),
        Price = product.Field<decimal>("ListPrice")
    });

Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
    Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
        productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim products As DataTable = ds.Tables("Product")

Dim query = products.AsEnumerable() _
    .Select(Function(product As DataRow) New With _
    { _
        .ProductName = product.Field(Of String)("Name"), _
        .ProductNumber = product.Field(Of String)("ProductNumber"), _
        .Price = product.Field(Of Decimal)("ListPrice") _
    })

Console.WriteLine("Product Info:")
For Each product In query
    Console.Write("Product name: " & product.ProductName)
    Console.Write("Product number: " & product.ProductNumber)
    Console.WriteLine("List price: $ " & product.Price)
Next

Composizione di queryComposing Queries

Come già detto in precedenza in questo argomento, la variabile di query viene usata solo per archiviare i comandi della query quando questa viene progettata in modo da restituire una sequenza di valori.As mentioned earlier in this topic, the query variable itself only stores the query commands when the query is designed to return a sequence of values. Se la query non contiene un metodo che causa l'esecuzione immediata, l'esecuzione effettiva della query viene posticipata finché non si esegue un'iterazione sulla variabile di query in un ciclo foreach o For Each.If the query does not contain a method that will cause immediate execution, the actual execution of the query is deferred until you iterate over the query variable in a foreach or For Each loop. L'esecuzione posticipata consente di combinare più query o di estendere una query.Deferred execution enables multiple queries to be combined or a query to be extended. Una query estesa viene modificata in modo da includere nuove operazioni. Le modifiche verranno quindi riflesse nell'eventuale esecuzione.When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. Nell'esempio seguente la prima query restituisce tutti i prodotti.In the following example, the first query returns all the products. La seconda query estende la prima usando Where per restituire tutti i prodotti di taglia "L":The second query extends the first by using Where to return all the products of size "L":

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> productsQuery =
    from product in products.AsEnumerable()
    select product;

IEnumerable<DataRow> largeProducts =
    productsQuery.Where(p => p.Field<string>("Size") == "L");

Console.WriteLine("Products of size 'L':");
foreach (DataRow product in largeProducts)
{
    Console.WriteLine(product.Field<string>("Name"));
}


' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim products As DataTable = ds.Tables("Product")

Dim productsQuery = From product In products.AsEnumerable() _
            Select product

Dim largeProducts = _
    productsQuery.Where(Function(p) p.Field(Of String)("Size") = "L")

Console.WriteLine("Products of size 'L':")
For Each product In largeProducts
    Console.WriteLine(product.Field(Of String)("Name"))
Next

Dopo aver eseguito una query, non è possibile comporre query aggiuntive e per tutte le query successive verranno usati gli operatori LINQLINQ in memoria.After a query has been executed, no additional queries can be composed, and all subsequent queries will use the in-memory LINQLINQ operators. La query verrà eseguita quando esegue un'iterazione sulla variabile di query in un foreach o For Each istruzione, o da una chiamata a uno del LINQLINQ gli operatori di conversione che causano l'esecuzione immediata.Query execution will occur when you iterate over the query variable in a foreach or For Each statement, or by a call to one of the LINQLINQ conversion operators that cause immediate execution. Tali operatori includono: ToList, ToArray, ToLookup e ToDictionary.These operators include the following: ToList, ToArray, ToLookup, and ToDictionary.

Nell'esempio seguente la prima query restituisce tutti i prodotti ordinati in base al prezzo di listino.In the following example, the first query returns all the products ordered by list price. Viene usato il metodo ToArray per forzare l'esecuzione immediata della query:The ToArray method is used to force immediate query execution:

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable products = ds.Tables["Product"];

IEnumerable<DataRow> query =
    from product in products.AsEnumerable()
    orderby product.Field<Decimal>("ListPrice") descending
    select product;

// Force immediate execution of the query.
IEnumerable<DataRow> productsArray = query.ToArray();

Console.WriteLine("Every price from highest to lowest:");
foreach (DataRow prod in productsArray)
{
    Console.WriteLine(prod.Field<Decimal>("ListPrice"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim products As DataTable = ds.Tables("Product")

Dim query = _
        From product In products.AsEnumerable() _
        Order By product.Field(Of Decimal)("ListPrice") Descending _
        Select product

' Force immediate execution of the query.
Dim productsArray = query.ToArray()

Console.WriteLine("Every price From highest to lowest:")
For Each prod In productsArray
    Console.WriteLine(prod.Field(Of Decimal)("ListPrice"))
Next

Vedere ancheSee Also

Guida per programmatoriProgramming Guide
Esecuzione di query su oggetti DataSetQuerying DataSets
Nozioni di base su LINQ in C#Getting Started with LINQ in C#
Introduzione a LINQ in Visual BasicGetting Started with LINQ in Visual Basic