Consultas en LINQ to DataSetQueries in LINQ to DataSet

Una consulta es una expresión que recupera datos de un origen de datos.A query is an expression that retrieves data from a data source. Las consultas se suelen expresar en un lenguaje de consulta especializado, como SQL para bases de datos relacionales y XQuery para XML.Queries are usually expressed in a specialized query language, such as SQL for relational databases and XQuery for XML. Por lo tanto, los programadores han tenido que aprender un lenguaje de consultas nuevo para cada tipo de origen de datos o formato de datos que consultan.Therefore, developers have had to learn a new query language for each type of data source or data format that they query. Language-Integrated Query (LINQ)Language-Integrated Query (LINQ) ofrece un modelo coherente y más sencillo para trabajar con los datos de varios formatos y orígenes de datos.offers a simpler, consistent model for working with data across various kinds of data sources and formats. En una consulta de LINQLINQ siempre se trabaja con objetos de programación.In a LINQLINQ query, you always work with programming objects.

Una operación de consulta de LINQLINQ consta de tres acciones: obtener el origen o los orígenes de datos, crear la consulta y ejecutar la consulta.A LINQLINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.

Los orígenes de datos que implementan la interfaz genérica IEnumerable<T> se pueden consultar a través de LINQLINQ.Data sources that implement the IEnumerable<T> generic interface can be queried through LINQLINQ. Al AsEnumerable llamar a DataTable en, se devuelve un objeto que implementa IEnumerable<T> la interfaz genérica, que actúa como origen de datos para las consultas de LINQ to DataSet.Calling AsEnumerable on a DataTable returns an object which implements the generic IEnumerable<T> interface, which serves as the data source for LINQ to DataSet queries.

En la consulta se especifica exactamente la información que se desea recuperar del origen de datos.In the query, you specify exactly the information that you want to retrieve from the data source. Una consulta también puede especificar cómo se debe ordenar, agrupar y conformar esa información antes de que se devuelva.A query can also specify how that information should be sorted, grouped, and shaped before it is returned. En LINQLINQ, una consulta se almacena en una variable.In LINQLINQ, a query is stored in a variable. Si la consulta está diseñada para devolver una secuencia de valores, la variable misma de la consulta debe ser de tipo enumerable.If the query is designed to return a sequence of values, the query variable itself must be a enumerable type. Esta variable de consulta no realiza ninguna acción y no devuelve datos; solamente almacena la información de la consulta.This query variable takes no action and returns no data; it only stores the query information. Tras crear una consulta debe ejecutarla para recuperar los datos.After you create a query you must execute that query to retrieve any data.

En una consulta que devuelve una secuencia de valores, la variable de consulta por sí misma nunca conserva los resultados de la consulta y solo almacena los comandos de la misma.In a query that returns a sequence of values, the query variable itself never holds the query results and only stores the query commands. La ejecución de la consulta se aplaza hasta que la variable de consulta se recorre en iteración en un bucle foreach o For Each.Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop. Esto se denomina ejecución aplazada; es decir, la ejecución de la consulta se produce una vez después de la construcción de la consulta.This is called deferred execution; that is, query execution occurs some time after the query is constructed. Esto significa que se puede ejecutar una consulta con la frecuencia que se desee.This means that you can execute a query as often as you want to. Esto es útil cuando, por ejemplo, se tiene una base de datos que otras aplicaciones están actualizando.This is useful when, for example, you have a database that is being updated by other applications. En su aplicación puede crear una consulta para recuperar la información más reciente y ejecutar de forma repetida la consulta, devolviendo cada vez la información actualizada.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 diferencia de las consultas en diferido, que devuelven una secuencia de valores, las consultas que devuelven un valor singleton se ejecutan inmediatamente.In contrast to deferred queries, which return a sequence of values, queries that return a singleton value are executed immediately. Algunos ejemplos de consultas singleton son Count, Max, Average y First.Some examples of singleton queries are Count, Max, Average, and First. Se ejecutan inmediatamente porque se necesitan los resultados de la consulta para calcular el resultado singleton.These execute immediately because the query results are required to calculate the singleton result. Por ejemplo, para buscar la media de los resultados de consultas, debe ejecutarse la consulta para que la función de cálculo de media tenga datos de entrada con los que trabajar.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. También puede usar los métodos ToList o ToArray en una consulta para forzar la ejecución inmediata de una consulta que no crea un valor 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. Esas técnicas para forzar la ejecución inmediata pueden ser útiles si desea almacenar en caché los resultados de una consulta.These techniques to force immediate execution can be useful when you want to cache the results of a query.

ConsultasQueries

LINQ to DataSet consultas se pueden formular en dos sintaxis diferentes: sintaxis de expresiones de consulta y sintaxis de consulta basada en métodos.LINQ to DataSet queries can be formulated in two different syntaxes: query expression syntax and method-based query syntax.

Sintaxis de expresiones de consultaQuery Expression Syntax

Las expresiones de consulta son una sintaxis de consulta declarativa.Query expressions are a declarative query syntax. Esta sintaxis permite a un desarrollador escribir consultas en C# o Visual Basic en un formato similar a SQL.This syntax enables a developer to write queries in C# or Visual Basic in a format similar to SQL. Si se utiliza la sintaxis de expresiones de consulta, se pueden realizar incluso operaciones complejas de filtrado, ordenación y agrupamiento en orígenes de datos con código mínimo.By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code. Para obtener más información, vea expresiones de consulta LINQ y operaciones básicas de consulta (Visual Basic).For more information, see LINQ Query Expressions and Basic Query Operations (Visual Basic).

El Common Language Runtime de .NET Framework (CLR) no puede leer la sintaxis de expresiones de consulta en sí.The .NET Framework common language runtime (CLR) cannot read the query expression syntax itself. Por lo tanto, en tiempo de compilación, las expresiones de consulta se traducen a algo que CLR no comprende: las llamadas a métodos.Therefore, at compile time, query expressions are translated to something that the CLR does understand: method calls. Estos métodos se conocen como operadores de consulta estándar.These methods are referred to as the standard query operators. Como programador, tiene la opción de llamarlos directamente utilizando la sintaxis de método en lugar de la sintaxis de consulta.As a developer, you have the option of calling them directly by using method syntax, instead of using query syntax. Para obtener más información, vea Query Syntax and Method Syntax in LINQ (Sintaxis de consulta y sintaxis de método en LINQ).For more information, see Query Syntax and Method Syntax in LINQ. Para obtener más información acerca de los operadores de consulta estándar, vea información general sobre operadores de consulta estándar.For more information about the standard query operators, see Standard Query Operators Overview.

El siguiente ejemplo usa Select para devolver todas las filas de la tabla Product y mostrar los nombres de producto.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

Sintaxis de consultas basadas en métodosMethod-Based Query Syntax

La otra forma de formular consultas LINQ to DataSet es mediante el uso de consultas basadas en métodos.The other way to formulate LINQ to DataSet queries is by using method-based queries. La sintaxis de consultas basadas en métodos es una secuencia de llamadas a métodos directas a los métodos de operador de LINQLINQ, pasando expresiones lambda como parámetros.The method-based query syntax is a sequence of direct method calls to LINQLINQ operator methods, passing lambda expressions as the parameters. Para obtener más información, vea Expresiones lambda.For more information, see Lambda Expressions.

Este ejemplo usa Select para devolver todas las filas de Product y mostrar los nombres de producto.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

Crear consultasComposing Queries

Tal y como se ha mencionado anteriormente en este tema, la variable de consulta solo almacena los comandos de la consulta cuando ésta se diseña para devolver una secuencia de valores.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. Si la consulta no contiene un método que cause una ejecución inmediata, la ejecución real de la consulta se aplaza hasta que la variable de consulta se recorra en iteración en un bucle 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. La ejecución aplazada permite combinar varias consultas o ampliar una consulta.Deferred execution enables multiple queries to be combined or a query to be extended. Cuando se amplía una consulta, se modifica para incluir las nuevas operaciones. La ejecución eventual reflejará los cambios.When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. En el siguiente ejemplo, la primera consulta devuelve todos los productos.In the following example, the first query returns all the products. La segunda consulta amplía la primera usando Where para devolver todos los productos del tamaño "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

Tras ejecutar una consulta no se pueden crear consultas adicionales y todas las consultas posteriores usarán los operadores de LINQLINQ en 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 ejecución de la consulta se producirá al recorrer en iteración foreach la For Each variable de consulta en una instrucción o, o mediante LINQLINQ una llamada a uno de los operadores de conversión que causan la ejecución inmediata.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. Entre estos operadores se incluyen los siguientes: ToList, ToArray, ToLookup y ToDictionary.These operators include the following: ToList, ToArray, ToLookup, and ToDictionary.

En el siguiente ejemplo, la primera consulta devuelve todos los productos ordenados por el precio de la lista.In the following example, the first query returns all the products ordered by list price. El método ToArray se usa para forzar la ejecución inmediata de la consulta: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

Vea tambiénSee also