Características de Visual Basic que admiten LINQ

Actualización: noviembre 2007

El nombre Language-Integrated Query (LINQ) hace referencia a la nueva tecnología incluida en Visual Basic 2008 que admite sintaxis de consulta y otras nuevas construcciones de lenguaje directamente en el lenguaje. Con LINQ, no tiene que aprender un nuevo lenguaje para realizar consultas contra un origen de datos externo. Puede realizar consultas contra datos de bases de datos relacionales, almacenes XML u objetos utilizando Visual Basic. Esta integración de capacidades de consulta en el lenguaje permite comprobar, en tiempo de compilación, errores de sintaxis y seguridad de tipos. Esta integración también le garantiza el conocimiento de los elementos esenciales para escribir consultas complejas y variadas en Visual Basic 2008.

Las secciones siguientes describen las nuevas construcciones de lenguaje con suficiente detalle como para permitirle empezar con la lectura de la documentación introductoria, ejemplos de código y aplicaciones de ejemplo. También puede hacer clic en los vínculos para encontrar explicaciones más detalladas de cómo las características del lenguaje contribuyen a permitir las consultas integradas en el lenguaje. Un buen lugar para empezar es Tutorial: Escribir consultas en Visual Basic.

Expresiones de consulta

Las expresiones de consulta en Visual Basic 2008 se pueden expresar en una sintaxis declarativa similar a la de SQL o XQuery. En tiempo de compilación, la sintaxis de consulta se convierte en llamadas a métodos en una implementación del proveedor LINQ de los métodos de extensión de operadores de consulta estándar. Las aplicaciones controlan qué operadores de consulta estándar están dentro del ámbito especificando el espacio de nombres adecuado con una instrucción Imports. La sintaxis para una expresión de consulta en Visual Basic es similar a ésta:

Dim londonCusts = From cust In customers _
                  Where cust.City = "London" _
                  Order By cust.Name Ascending _
                  Select cust.Name, cust.Phone

Para obtener más información, vea Introducción a LINQ en Visual Basic.

Variables con tipo implícito

En lugar de especificar explícitamente un tipo al declarar e inicializar una variable, puede permitir ahora al compilador deducir y asignar el tipo, como se muestra en el ejemplo siguiente. Esto se conoce como inferencia de tipo de variable local.

Nota:

La inferencia de tipo de variable local sólo funciona cuando define una variable local dentro del cuerpo de un método con Option Infer establecida en On. On es el valor predeterminado para nuevos proyectos en LINQ. Para obtener más información, vea Option Infer (Instrucción).

' The variable number will be typed as an integer.
Dim aNumber = 5

' The variable name will be typed as a String.
Dim aName = "Virginia"
Nota:

En Visual Basic 2005 y versiones anteriores, estos ejemplos se compilan bien, pero el tipo asignado a aNumber y aName es Object. Por consiguiente, un proyecto existente que se vuelve a compilar en Visual Basic 2008 con Option Infer establecida en On puede comportarse de manera diferente que en versiones anteriores del lenguaje.

' Query example.
' If numbers is a one-dimensional array of integers, num will be typed
' as an integer and numQuery will be typed as IEnumerable(Of Integer)--
' basically a collection of integers.

Dim numQuery = From num In numbers _
               Where num Mod 2 = 0 _
               Select num

Las variables declaradas de esta manera presentan un establecimiento inflexible de tipos, al igual que las variables cuyo tipo se especifica explícitamente. La inferencia de tipo de variable local permite crear tipos anónimos, que son necesarios para las consultas LINQ, pero también se puede utilizar para cualquier variable local.

Para obtener más información, vea Inferencia de tipo de variable local.

Inicializadores de objeto

Los inicializadores de objeto se utilizan en expresiones de consulta cuando se debe crear un tipo anónimo para albergar los resultados de una consulta. También se pueden utilizar para inicializar objetos de tipos con nombre fuera de las consultas. Utilizando un inicializador de objeto, puede inicializar un objeto en una sola línea sin llamar explícitamente a un constructor. Suponiendo que tiene una clase denominada Customer con propiedades públicas Name y Phone, además de otras propiedades, un inicializador de objeto se puede utilizar de esta manera:

Dim aCust As Customer = New Customer With {.Name = "Mike", _
                                           .Phone = "555-0212"}

Para obtener más información, vea Inicializadores de objeto: Tipos con nombre y anónimos.

Tipos anónimos

Los tipos anónimos proporcionan una manera práctica de agrupar temporalmente un conjunto de propiedades en un elemento que se desea incluir en un resultado de la consulta. Esto permite elegir cualquier combinación de campos disponibles en la consulta, en cualquier orden, sin definir un tipo de datos con nombre para el elemento.

El tipo anónimo lo construye dinámicamente el compilador. El nombre del tipo es asignado por el compilador, y podría cambiar con cada nueva compilación. Por tanto, el nombre no se puede utilizar directamente. Los tipos anónimos se inicializan de la manera siguiente:

' Outside a query.
Dim product = New With {.Name = "paperclips", .Price = 1.29}

' Inside a query.
' You can use the existing member names of the selected fields, as was
' shown previously in the Query Expressions section of this topic.
Dim londonCusts1 = From cust In customers _
                   Where cust.City = "London" _
                   Select cust.Name, cust.Phone

' Or you can specify new names for the selected fields.
Dim londonCusts2 = From cust In customers _
                   Where cust.City = "London" _
                   Select CustomerName = cust.Name, _
                   CustomerPhone = cust.Phone

Para obtener más información, vea Tipos anónimos.

Métodos de extensión

Los métodos de extensión permiten agregar métodos a un tipo de datos o a una interfaz desde fuera de la definición. Esta característica permite agregar nuevos métodos a un tipo existente sin tener que modificar el tipo. Los operadores de consulta estándar son un conjunto de métodos de extensión que proporcionan funcionalidad de consulta LINQ para cualquier tipo que implementa IEnumerable<T>. Otras extensiones a IEnumerable<T> incluyen Count, Union y Intersect.

El siguiente método de extensión agrega un método de impresión a la clase String.

' Import System.Runtime.CompilerServices to use the Extension attribute.
<Extension()> _
    Public Sub Print(ByVal str As String)
    Console.WriteLine(str)
End Sub

Al método se le llama como a un método de instancia ordinario de String:

Dim greeting As String = "Hello"
greeting.Print()

Para obtener más información, vea Métodos de extensión (Visual Basic).

Expresiones lambda

Una expresión lambda es una función sin nombre que calcula y devuelve un solo valor. A diferencia de las funciones con nombre, una expresión lambda se puede definir y ejecutar al mismo tiempo. El ejemplo siguiente muestra 4.

Console.WriteLine((Function(num As Integer) num + 1)(3))

Puede asignar la definición de la expresión lambda a un nombre de variable y, a continuación, utilizar el nombre para llamar a la función. El ejemplo siguiente también muestra 4.

Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))

En LINQ, las expresiones lambda subyacen a muchos de los operadores de consulta estándar. El compilador crea expresiones lambda para capturar los cálculos definidos en los métodos de consulta básicos como Where, Select, Order By, Take While, etc.

Por ejemplo, el código siguiente define una consulta que devuelve todos los alumnos de último curso de una lista de alumnos.

Dim seniorsQuery = From stdnt In students _
                   Where stdnt.Year = "Senior" _
                   Select stdnt

La definición de la consulta se compila en código similar al del ejemplo siguiente, el cual utiliza dos expresiones lambda para especificar los argumentos de Where y Select.

Dim seniorsQuery2 = students _
    .Where(Function(st) st.Year = "Senior") _
    .Select(Function(s) s)

Cualquiera de las versiones se puede ejecutar mediante un bucle For Each:

For Each senior In seniorsQuery
    Console.WriteLine(senior.Last & ", " & senior.First)
Next

Para obtener más información, vea Expresiones lambda.

Vea también

Tareas

Ejemplos de consultas (Visual Basic)

Conceptos

LINQ y cadenas

Otros recursos

Language-Integrated Query (LINQ)

Introducción a LINQ en Visual Basic