Compartir a través de


Consultas en LINQ to DataSet

Una consulta es una expresión que recupera datos de un origen de datos. Las consultas normalmente se expresan en un lenguaje de consulta especializado, como SQL para bases de datos relacionales y XQuery para XML. Por lo tanto, los desarrolladores han tenido que aprender un nuevo lenguaje de consulta para cada tipo de origen de datos o formato de datos que consultan. Language-Integrated Query (LINQ) ofrece un modelo más sencillo y coherente para trabajar con datos en varios tipos de orígenes de datos y formatos. En una consulta LINQ, siempre se trabaja con objetos de programación.

Una operación de consulta LINQ consta de tres acciones: obtener el origen de datos o los orígenes, crear la consulta y ejecutar la consulta.

Los orígenes de datos que implementan la IEnumerable<T> interfaz genérica se pueden consultar mediante LINQ. Realizar una llamada AsEnumerable sobre un DataTable devuelve un objeto que implementa la interfaz genérica IEnumerable<T>, la cual actúa como fuente de datos para las consultas LINQ to DataSet.

En la consulta, especifique exactamente la información que desea recuperar del origen de datos. Una consulta también puede especificar cómo se debe ordenar, agrupar y dar forma a esa información antes de que se devuelva. En LINQ, una consulta se almacena en una variable. Si la consulta está diseñada para devolver una secuencia de valores, la propia variable de consulta debe ser un tipo enumerable. Esta variable de consulta no realiza ninguna acción y no devuelve ningún dato; solo almacena la información de consulta. Después de crear una consulta, debe ejecutar esa consulta para recuperar los datos.

En una consulta que devuelve una secuencia de valores, la propia variable de consulta nunca contiene los resultados de la consulta y solo almacena los comandos de consulta. La ejecución de la consulta se aplaza hasta que la variable de consulta se itera dentro de un bucle foreach o For Each. Esto se denomina ejecución diferida; es decir, la ejecución de consultas se produce algún tiempo después de construir la consulta. Esto significa que puede ejecutar una consulta con tanta frecuencia como desee. Esto resulta útil cuando, por ejemplo, tiene una base de datos que otras aplicaciones actualizan. En la aplicación, puede crear una consulta para recuperar la información más reciente y ejecutar repetidamente la consulta, devolviendo la información actualizada cada vez.

A diferencia de las consultas diferidas, que devuelven una secuencia de valores, las consultas que devuelven un valor singleton se ejecutan inmediatamente. Algunos ejemplos de consultas singleton son Count, Max, Averagey First. Se ejecutan inmediatamente porque se necesitan los resultados de la consulta para calcular el resultado singleton. Por ejemplo, para encontrar el promedio de los resultados de la consulta, la consulta debe ejecutarse para que la función de promedio tenga datos de entrada con los que trabajar. También puede usar los métodos ToList o ToArray en una consulta para forzar la ejecución inmediata de una consulta que no genera un valor único. Estas técnicas para forzar la ejecución inmediata pueden ser útiles cuando desea almacenar en caché los resultados de una consulta.

Preguntas

Las consultas LINQ to DataSet se pueden formular en dos sintaxis diferentes: sintaxis de expresiones de consulta y sintaxis de consulta basada en métodos.

Sintaxis de expresiones de consulta

Las expresiones de consulta son una sintaxis de consulta declarativa. Esta sintaxis permite al desarrollador escribir consultas en C# o Visual Basic en un formato similar a SQL. Mediante la sintaxis de expresiones de consulta, puede realizar incluso operaciones complejas de filtrado, ordenación y agrupación en orígenes de datos con código mínimo. Para obtener más información, vea Expresiones de consulta LINQ y Operaciones de consulta básicas (Visual Basic).

Common Language Runtime (CLR) de .NET Framework no puede leer la propia sintaxis de expresión de consulta. Por lo tanto, en tiempo de compilación, las expresiones de consulta se traducen a algo que CLR entiende: llamadas de método. Estos métodos se conocen como operadores de consulta estándar. Como desarrollador, tiene la opción de llamarlos directamente mediante la sintaxis del método, en lugar de usar la sintaxis de consulta. Para obtener más información, vea Sintaxis de consulta y sintaxis del método en LINQ. Para obtener más información sobre los operadores de consulta estándar, vea Información general sobre operadores de consulta estándar.

En el ejemplo siguiente se usa Select para devolver todas las filas de Product la tabla y mostrar los nombres de producto.

// 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 consulta para Method-Based

La otra manera de formular consultas LINQ to DataSet es mediante consultas basadas en métodos. La sintaxis de consulta basada en métodos es una secuencia de llamadas de método directo a métodos de operador LINQ, pasando expresiones lambda como parámetros. Para obtener más información, vea Expresiones lambda.

En este ejemplo se usa Select para devolver todas las filas de Product y mostrar los nombres de los productos.

// 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: {productInfo.ProductName} Product number: {productInfo.ProductNumber} List price: ${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

Redacción de consultas

Como se mencionó anteriormente en este tema, la propia variable de consulta solo almacena los comandos de consulta cuando la consulta está diseñada para devolver una secuencia de valores. Si la consulta no contiene un método que provocará la ejecución inmediata, la ejecución real de la consulta se aplaza hasta que se recorre en iteración la variable de consulta en un foreach bucle o For Each . La ejecución diferida permite combinar varias consultas o ampliar una consulta. Cuando se extiende una consulta, se modifica para incluir las nuevas operaciones y la ejecución final reflejará los cambios. En el ejemplo siguiente, la primera consulta devuelve todos los productos. La segunda consulta amplía la primera mediante Where para devolver todos los productos de tamaño "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

Una vez ejecutada una consulta, no se puede crear ninguna consulta adicional y todas las consultas posteriores usarán los operadores LINQ en memoria. La ejecución de la consulta se producirá cuando se recorra en iteración la variable de consulta en una instrucción foreach o For Each, o mediante una llamada a uno de los operadores de conversión de LINQ que provocará una ejecución inmediata. Estos operadores incluyen lo siguiente: ToList, ToArray, ToLookupy ToDictionary.

En el ejemplo siguiente, la primera consulta devuelve todos los productos ordenados por precio de lista. El ToArray método se usa para forzar la ejecución inmediata de consultas:

// 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

Consulte también