Introducción a LINQ en Visual Basic
Language Integrated Query (LINQ) agrega capacidades de consulta a Visual Basic y proporciona capacidades sencillas y eficaces al trabajar con todo tipo de datos. En lugar de enviar una consulta a una base de datos para su procesamiento o de trabajar con distintas sintaxis de consulta para cada tipo de datos que se esté buscando, LINQ presenta las consultas como parte del lenguaje Visual Basic. Utiliza una sintaxis unificada independientemente del tipo de datos.
LINQ permite consultar datos de una base de datos SQL Server, XML, colecciones y matrices en memoria, conjuntos de datos de ADO.NET o cualquier otro origen de datos local o remoto compatible con LINQ. Todo esto puede hacerse mediante elementos comunes del lenguaje Visual Basic. Dado que las consultas se escriben en el lenguaje Visual Basic, los resultados de la consulta se devuelven como objetos fuertemente tipados. Estos objetos son compatibles con IntelliSense, lo que le permite escribir código más rápidamente y detectar errores en las consultas en tiempo de compilación en lugar de en tiempo de ejecución. Las consultas LINQ se pueden utilizar como el origen de consultas adicionales para refinar los resultados. También se pueden enlazar a controles para que los usuarios puedan ver y modificar fácilmente los resultados de la consulta.
Por ejemplo, en el siguiente ejemplo de código se muestra una consulta LINQ que devuelve una lista de clientes de una colección y los agrupa basándose en su ubicación.
' Obtain a list of customers.
Dim customers As List(Of Customer) = GetCustomers()
' Return customers that are grouped based on country.
Dim countries = From cust In customers
Order By cust.Country, cust.City
Group By CountryName = cust.Country
Into CustomersInCountry = Group, Count()
Order By CountryName
' Output the results.
For Each country In countries
Debug.WriteLine(country.CountryName & " count=" & country.Count)
For Each customer In country.CustomersInCountry
Debug.WriteLine(" " & customer.CompanyName & " " & customer.City)
Next
Next
' Output:
' Canada count=2
' Contoso, Ltd Halifax
' Fabrikam, Inc. Vancouver
' United States count=1
' Margie's Travel Redmond
Ejecución de los ejemplos
Para ejecutar los ejemplos de la introducción y de la sección Estructura de una consulta LINQ, incluya el siguiente código, que devuelve listas de clientes y pedidos.
' Return a list of customers.
Private Function GetCustomers() As List(Of Customer)
Return New List(Of Customer) From
{
New Customer With {.CustomerID = 1, .CompanyName = "Contoso, Ltd", .City = "Halifax", .Country = "Canada"},
New Customer With {.CustomerID = 2, .CompanyName = "Margie's Travel", .City = "Redmond", .Country = "United States"},
New Customer With {.CustomerID = 3, .CompanyName = "Fabrikam, Inc.", .City = "Vancouver", .Country = "Canada"}
}
End Function
' Return a list of orders.
Private Function GetOrders() As List(Of Order)
Return New List(Of Order) From
{
New Order With {.CustomerID = 1, .Amount = "200.00"},
New Order With {.CustomerID = 3, .Amount = "600.00"},
New Order With {.CustomerID = 1, .Amount = "300.00"},
New Order With {.CustomerID = 2, .Amount = "100.00"},
New Order With {.CustomerID = 3, .Amount = "800.00"}
}
End Function
' Customer Class.
Private Class Customer
Public Property CustomerID As Integer
Public Property CompanyName As String
Public Property City As String
Public Property Country As String
End Class
' Order Class.
Private Class Order
Public Property CustomerID As Integer
Public Property Amount As Decimal
End Class
Proveedores LINQ
Un proveedor LINQ asigna las consultas LINQ de Visual Basic al origen de datos que se está consultando. Cuando usted escribe una consulta LINQ, el proveedor toma esa consulta y la traduce en comandos que podrá ejecutar el origen de datos. El proveedor también convierte los datos del origen en los objetos que forman el resultado de su consulta. Por último, convierte los objetos en datos cuando envía actualizaciones al origen de datos.
Visual Basic incluye los siguientes proveedores LINQ.
Proveedor | Descripción |
---|---|
LINQ to Objects | El proveedor LINQ to Objects le permite consultar las matrices y colecciones en memoria. Si un objeto es compatible con las interfaces IEnumerable o IEnumerable<T>, el proveedor LINQ to Objects le permite consultarlo. Puede habilitar el proveedor LINQ to Objects si importa el espacio de nombres System.Linq, que se importa de manera predeterminada para todos los proyectos de Visual Basic. Para obtener más información sobre el proveedor LINQ to Objects, vea LINQ to Objects. |
LINQ a SQL | El proveedor LINQ to SQL le permite consultar y modificar datos en una base de datos de SQL Server. Esto hace que sea fácil asignar el modelo de objetos de una aplicación a las tablas y los objetos de una base de datos. Visual Basic facilita el trabajo con LINQ to SQL mediante la inclusión de Object Relational Designer. Este diseñador se usa para crear un modelo de objetos en una aplicación que se asigna a los objetos de una base de datos. Object Relational Designer también proporciona funcionalidad para asignar procedimientos almacenados y funciones al objeto DataContext, que administra la comunicación con la base de datos y almacena el estado de las comprobaciones de simultaneidad optimista. Para obtener más información sobre el proveedor LINQ to SQL, vea LINQ to SQL. Para obtener más información sobre Object Relational Designer, vea Herramientas de LINQ to SQL en Visual Studio. |
LINQ to XML | El proveedor LINQ to XML le permite consultar y modificar XML. Puede modificar XML en memoria o puede cargar XML desde un archivo y guardarlo en él. Además, el proveedor LINQ to XML habilita literales XML y propiedades de eje XML que permiten escribir XML directamente en el código de Visual Basic. Para obtener más información, vea XML. |
LINQ to DataSet | El proveedor LINQ to DataSet permite consultar y actualizar los datos de un conjunto de datos de ADO.NET. Puede agregar la eficacia de LINQ a las aplicaciones que utilicen conjuntos de datos con el fin de simplificar y ampliar las funcionalidades de consulta, agregado y actualización de los datos del conjunto de datos. Para más información, vea LINQ to DataSet. |
Estructura de una consulta LINQ
Una consulta LINQ, que a veces se conoce como una expresión de consulta, consta de una combinación de cláusulas de consulta que identifican los orígenes de datos y las variables de iteración de la consulta. Una expresión de consulta también incluye instrucciones para ordenar, filtrar, agrupar y combinar, o cálculos para aplicar al origen de datos. La sintaxis de las expresiones de consulta se parece a la sintaxis de SQL; por lo tanto, le puede resultar familiar gran parte de la sintaxis.
Una expresión de consulta comienza con una cláusula From
. Esta cláusula identifica los datos de origen de una consulta y las variables que se usan para referirse individualmente a cada elemento de los datos de origen. Estas variables se conocen como variables de rango o variables de iteración. La cláusula From
se requiere para una consulta, excepto para consultas Aggregate
, donde la cláusula From
es opcional. Una vez que se hayan identificado el ámbito y el origen de la consulta en las cláusulas From
o Aggregate
, puede incluir cualquier combinación de cláusulas de consulta para refinar la consulta. Para obtener detalles sobre las cláusulas de consulta, vea los operadores de consulta LINQ de Visual Basic más adelante en este tema. Por ejemplo, la siguiente consulta identifica una colección de origen de datos de cliente como la variable customers
y una variable de iteración denominada cust
.
Dim customers = GetCustomers()
Dim queryResults = From cust In customers
For Each result In queryResults
Debug.WriteLine(result.CompanyName & " " & result.Country)
Next
' Output:
' Contoso, Ltd Canada
' Margie's Travel United States
' Fabrikam, Inc. Canada
Este ejemplo es una consulta válida por sí misma; sin embargo, la consulta es mucho más eficaz cuando agrega más cláusulas de consulta para refinar los resultados. Por ejemplo, puede agregar una cláusula Where
para filtrar los resultados mediante uno o varios valores. Las expresiones de consulta son una sola línea de código; puede simplemente anexar cláusulas de consulta adicionales al final de la consulta. Puede dividir una consulta en varias líneas de texto para mejorar su legibilidad mediante el carácter de continuación de línea de subrayado (_). En el siguiente ejemplo de código se muestra una consulta que incluye una cláusula Where
.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Otra cláusula de consulta eficaz es la cláusula Select
, que sólo le permite devolver los campos seleccionados del origen de datos. Las consultas LINQ devuelven colecciones enumerables de objetos fuertemente tipados. Una consulta puede devolver una colección de tipos anónimos o de tipos con nombre. Puede utilizar la cláusula Select
para que solo se devuelva un único campo del origen de datos. Al hacerlo, el tipo de la colección devuelto es el tipo de ese campo único. También puede utilizar la cláusula Select
para devolver varios campos del origen de datos. Al hacerlo, el tipo de la colección devuelto es un nuevo tipo anónimo. También puede hacer coincidir los campos devueltos por la consulta a los campos de un tipo con nombre especificado. En el siguiente ejemplo de código se muestra una expresión de consulta que devuelve una colección de tipos anónimos con miembros rellenados con datos de los campos seleccionados del origen de datos.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName, cust.Country
Las consultas LINQ también pueden utilizarse para combinar varios orígenes de datos y devolver un único resultado. Esto puede hacerse con una o más cláusulas From
o mediante las cláusulas de consulta Join
o Group Join
. En el siguiente ejemplo de código se muestra una expresión de consulta que combina datos de clientes y pedidos y devuelve una colección de tipos anónimos que contiene datos de clientes y pedidos.
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers, ord In orders
Where cust.CustomerID = ord.CustomerID
Select cust, ord
For Each result In queryResults
Debug.WriteLine(result.ord.Amount & " " & result.ord.CustomerID & " " & result.cust.CompanyName)
Next
' Output:
' 200.00 1 Contoso, Ltd
' 300.00 1 Contoso, Ltd
' 100.00 2 Margie's Travel
' 600.00 3 Fabrikam, Inc.
' 800.00 3 Fabrikam, Inc.
Puede utilizar la cláusula Group Join
para crear un resultado de consulta jerárquica que contenga una colección de objetos Customer. Cada objeto Customer tiene una propiedad que contiene una colección de todos los pedidos para ese cliente. En el siguiente ejemplo de código se muestra una expresión de consulta que combina datos de clientes y pedidos como un resultado jerárquico y devuelve una colección de tipos anónimos. La consulta devuelve un tipo que incluye una propiedad CustomerOrders
que contiene una colección de datos de pedidos del cliente. También incluye una propiedad OrderTotal
que contiene la suma de los totales de todos los pedidos de ese cliente. (Esta consulta es equivalente a una combinación externa izquierda).
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
OrderTotal = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, OrderTotal
For Each result In queryResults
Debug.WriteLine(result.OrderTotal & " " & result.CustomerID & " " & result.CompanyName)
For Each ordResult In result.CustomerOrders
Debug.WriteLine(" " & ordResult.Amount)
Next
Next
' Output:
' 500.00 1 Contoso, Ltd
' 200.00
' 300.00
' 100.00 2 Margie's Travel
' 100.00
' 1400.00 3 Fabrikam, Inc.
' 600.00
' 800.00
Hay varios operadores de consulta LINQ adicionales que puede utilizar para crear expresiones de consulta eficaces. En la siguiente sección de este tema se describen las diversas cláusulas de consulta que puede incluir en una expresión de consulta. Para obtener detalles sobre las cláusulas de consulta de Visual Basic, vea Consultas.
Operadores de consulta LINQ de Visual Basic
Las clases en el espacio de nombres System.Linq y los otros espacios de nombres compatibles con consultas LINQ incluyen métodos a los que puede llamar para crear y refinar las consultas en función de las necesidades de su aplicación. Visual Basic incluye palabras clave para las siguientes cláusulas de consulta comunes. Para obtener detalles sobre las cláusulas de consulta de Visual Basic, vea Consultas.
Cláusula From
Para iniciar una consulta se requiere From
(Cláusula) o una cláusula Aggregate
. Una cláusula From
especifica una colección de origen y una variable de iteración de una consulta. Por ejemplo:
' Returns the company name for all customers for which
' the Country is equal to "Canada".
Dim names = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName
Select (cláusula)
Opcional. Select
(Cláusula) declara un conjunto de variables de iteración para una consulta. Por ejemplo:
' Returns the company name and ID value for each
' customer as a collection of a new anonymous type.
Dim customerList = From cust In customers
Select cust.CompanyName, cust.CustomerID
Si no se especifica una cláusula Select
, las variables de iteración de la consulta se componen de las variables de iteración especificadas por la cláusula From
o Aggregate
.
Cláusula WHERE
Opcional. Where
(Cláusula) especifica una condición de filtrado para una consulta. Por ejemplo:
' Returns all product names for which the Category of
' the product is "Beverages".
Dim names = From product In products
Where product.Category = "Beverages"
Select product.Name
Order By (cláusula)
Opcional. Order By
(Cláusula) especifica el criterio de ordenación de las columnas de una consulta. Por ejemplo:
' Returns a list of books sorted by price in
' ascending order.
Dim titlesAscendingPrice = From b In books
Order By b.price
Join (cláusula)
Opcional. Join
(Cláusula) combina dos colecciones en una sola. Por ejemplo:
' Returns a combined collection of all of the
' processes currently running and a descriptive
' name for the process taken from a list of
' descriptive names.
Dim processes = From proc In Process.GetProcesses
Join desc In processDescriptions
On proc.ProcessName Equals desc.ProcessName
Select proc.ProcessName, proc.Id, desc.Description
Group By (cláusula)
Opcional. Group By
(Cláusula) agrupa los elementos de los resultados de una consulta. Se puede usar para aplicar funciones de agregado a cada grupo. Por ejemplo:
' Returns a list of orders grouped by the order date
' and sorted in ascending order by the order date.
Dim orderList = From order In orders
Order By order.OrderDate
Group By OrderDate = order.OrderDate
Into OrdersByDate = Group
Group Join (cláusula)
Opcional. Group Join
(Cláusula) combina dos colecciones en una sola colección jerárquica. Por ejemplo:
' Returns a combined collection of customers and
' customer orders.
Dim customerList = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
TotalOfOrders = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, TotalOfOrders
Aggregate (cláusula)
Para iniciar una consulta se requiere Aggregate
(Cláusula) o una cláusula From
. Una cláusula Aggregate
aplica una o más funciones agregadas a una colección. Por ejemplo, puede usar la cláusula Aggregate
para calcular una suma de todos los elementos devueltos por una consulta, como se hace en el siguiente ejemplo.
' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
Into Sum(order.Amount)
También puede utilizar la cláusula Aggregate
para modificar una consulta. Por ejemplo, puede utilizar la cláusula Aggregate
para realizar un cálculo en una colección de consultas relacionada. Por ejemplo:
' Returns the customer company name and largest
' order amount for each customer.
Dim customerMax = From cust In customers
Aggregate order In cust.Orders
Into MaxOrder = Max(order.Amount)
Select cust.CompanyName, MaxOrder
Let (cláusula)
Opcional. Let
(Cláusula) calcula un valor y lo asigna a una nueva variable de la consulta. Por ejemplo:
' Returns a list of products with a calculation of
' a ten percent discount.
Dim discountedProducts = From prod In products
Let Discount = prod.UnitPrice * 0.1
Where Discount >= 50
Select prod.Name, prod.UnitPrice, Discount
Distinct (cláusula)
Opcional. Una cláusula Distinct
restringe los valores de la variable de iteración actual para eliminar los valores duplicados en los resultados de la consulta. Por ejemplo:
' Returns a list of cities with no duplicate entries.
Dim cities = From item In customers
Select item.City
Distinct
Skip (cláusula)
Opcional. Skip
(Cláusula) omite un número especificado de elementos de una colección y luego devuelve los elementos restantes. Por ejemplo:
' Returns a list of customers. The first 10 customers
' are ignored and the remaining customers are
' returned.
Dim customerList = From cust In customers
Skip 10
Skip While (cláusula)
Opcional. Skip While
(Cláusula) omite elementos de una colección siempre que el valor de una condición especificada sea true
y luego devuelve los elementos restantes. Por ejemplo:
' Returns a list of customers. The query ignores all
' customers until the first customer for whom
' IsSubscriber returns false. That customer and all
' remaining customers are returned.
Dim customerList = From cust In customers
Skip While IsSubscriber(cust)
Take (cláusula)
Opcional. Take
(Cláusula) devuelve un número especificado de elementos contiguos desde el principio de una colección. Por ejemplo:
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Take While (cláusula)
Opcional. Take While
(Cláusula) incluye elementos de una colección siempre que el valor de una condición especificada sea true
y omite los elementos restantes. Por ejemplo:
' Returns a list of customers. The query returns
' customers until the first customer for whom
' HasOrders returns false. That customer and all
' remaining customers are ignored.
Dim customersWithOrders = From cust In customers
Order By cust.Orders.Count Descending
Take While HasOrders(cust)
Uso de características de consulta LINQ adicionales
Puede usar características de consulta LINQ adicionales llamando a los miembros de los tipos de enumerables y consultables proporcionados por LINQ. Puede utilizar estas funciones adicionales llamando a un operador de consulta determinado en el resultado de una expresión de consulta. Por ejemplo, en el siguiente ejemplo se usa el método Enumerable.Union para combinar los resultados de dos consultas en los resultados de una. Utiliza el método Enumerable.ToList para devolver el resultado de la consulta como una lista genérica.
Public Function GetAllCustomers() As List(Of Customer)
Dim customers1 = From cust In domesticCustomers
Dim customers2 = From cust In internationalCustomers
Dim customerList = customers1.Union(customers2)
Return customerList.ToList()
End Function
Para obtener detalles sobre las capacidades adicionales de LINQ, vea Información general sobre operadores de consulta estándar.
Conexión a una base de datos mediante LINQ to SQL
En Visual Basic, los objetos de base de datos SQL Server, como tablas, vistas y procedimientos almacenados, a los que se quiere acceder se identifican mediante un archivo LINQ to SQL. Un archivo LINQ to SQL tiene una extensión .dbml.
Si tiene una conexión válida a una base de datos SQL Server, puede agregar al proyecto una plantilla de elementos Clases LINQ to SQL. De este modo se mostrará el Object Relational Designer (O/R Designer). Object Relational Designer permite arrastrar los elementos a los que se quiere acceder en el código desde el Explorador de servidores/Explorador de bases de datos a la superficie del diseñador. El archivo LINQ to SQL agrega un objeto DataContext al proyecto. Este objeto incluye propiedades y colecciones para las tablas y vistas a las que desea acceder y métodos para los procedimientos almacenados a los que desea llamar. Después de haber guardado los cambios en el archivo LINQ to SQL (.dbml), puede acceder a estos objetos en el código haciendo referencia al objeto DataContext definido por el O/R Designer. El nombre del objeto DataContext del proyecto se determina en función del nombre del archivo LINQ to SQL. Por ejemplo, un archivo LINQ to SQL denominado Northwind.dbml creará un objeto DataContext denominado NorthwindDataContext
.
Para obtener ejemplos con instrucciones paso a paso, vea Procedimiento para consultar una base de datos y Procedimiento para llamar a un procedimiento almacenado.
Características de Visual Basic que admiten LINQ
Visual Basic incluye otras características destacables que simplifican el uso de LINQ y reducen la cantidad de código que se debe escribir para realizar consultas LINQ. que incluyen la siguiente información:
Tipos anónimos, que permiten crear un nuevo tipo basado en un resultado de consulta.
Variables con tipo implícito, que permiten aplazar la especificación de un tipo y dejan que el compilador deduzca el tipo en función del resultado de la consulta.
Métodos de extensión, que permiten extender un tipo existente con métodos propios sin modificar el tipo en sí.
Para obtener detalles, vea Características de Visual Basic que admiten LINQ.
Ejecución de consultas aplazada e inmediata
La ejecución de una consulta se realiza de manera independiente con respecto a la creación de una consulta. Después de crear una consulta, un mecanismo independiente desencadena su ejecución. Una consulta se puede ejecutar tan pronto como se define (ejecución inmediata), o se puede almacenar la definición y se puede ejecutar la consulta más adelante (ejecución aplazada).
De forma predeterminada, cuando crea una consulta, la propia consulta no se ejecuta inmediatamente. En su lugar, la definición de la consulta se almacena en la variable que se utiliza para hacer referencia al resultado de la consulta. Cuando se accede a la variable de resultado de la consulta más adelante en el código, como, por ejemplo, en un bucle For…Next
, se ejecuta la consulta. Este proceso se conoce como ejecución aplazada.
Las consultas también se pueden ejecutar cuando se definen, lo que se conoce como ejecución inmediata. Puede desencadenar la ejecución inmediata aplicando un método que requiera acceso a elementos individuales del resultado de la consulta. Esto puede ser el resultado de incluir una función de agregado, como Count
, Sum
, Average
, Min
o Max
. Para obtener más información sobre las funciones de agregado, vea Aggregate (Cláusula).
El uso de los métodos ToList
o ToArray
también fuerza la ejecución inmediata. Esto le puede resultar útil cuando desee ejecutar la consulta inmediatamente y almacenar en caché los resultados. Para obtener más información sobre estos métodos, vea Conversión de tipos de datos.
Para obtener más información sobre la ejecución de consultas, vea Escritura de la primera consulta con LINQ.
XML en Visual Basic
Las características XML de Visual Basic incluyen literales XML y propiedades de eje XML, que permiten crear, consultar y modificar XML, así como acceder a él, en el código. Los literales XML le permiten escribir XML directamente en el código. El compilador de Visual Basic trata el XML como un objeto de datos de primera clase.
En el siguiente ejemplo de código se muestra cómo crear un elemento XML, acceder a sus subelementos y atributos y consultar el contenido del elemento mediante LINQ.
' Place Imports statements at the top of your program.
Imports <xmlns:ns="http://SomeNamespace">
Module Sample1
Sub SampleTransform()
' Create test by using a global XML namespace prefix.
Dim contact =
<ns:contact>
<ns:name>Patrick Hines</ns:name>
<ns:phone ns:type="home">206-555-0144</ns:phone>
<ns:phone ns:type="work">425-555-0145</ns:phone>
</ns:contact>
Dim phoneTypes =
<phoneTypes>
<%= From phone In contact.<ns:phone>
Select <type><%= phone.@ns:type %></type>
%>
</phoneTypes>
Console.WriteLine(phoneTypes)
End Sub
End Module
Para obtener más información, vea XML.
Recursos relacionados
Tema | Descripción |
---|---|
XML | Describe las características XML de Visual Basic que se pueden consultar y que permiten incluir XML como objetos de datos de primera clase en el código de Visual Basic. |
Consultas | Proporciona información de referencia sobre las cláusulas de consulta disponibles en Visual Basic. |
LINQ (Language Integrated Query) | Incluye información general, instrucciones de programación y ejemplos de LINQ. |
LINQ to SQL | Incluye información general, guía de programación y ejemplos de LINQ to SQL. |
LINQ to Objects | Incluye información general, guía de programación y ejemplos de LINQ to Objects. |
LINQ to ADO.NET (Página de portal) | Incluye vínculos a información general, instrucciones de programación y ejemplos de LINQ to ADO.NET. |
LINQ to XML | Incluye información general, guía de programación y ejemplos de LINQ to XML. |
Temas de procedimientos y tutoriales
Cómo: Consultar una base de datos
Cómo: Llamar a un procedimiento almacenado
Cómo: Modificar datos en una bases de datos
Cómo: Combinar datos con cláusulas Join
Cómo: Ordenar los resultados de una consulta
Cómo: Filtrar los resultados de una consulta
Cómo: Hacer el recuento, la suma o el promedio de datos
Cómo: Buscar los valores máximo y mínimo en el resultado de una consulta
Capítulos destacados de libros
Capítulo 17: LINQ de Programación de Visual Basic 2008