Relaciones entre tipos en operaciones de consulta (Visual Basic)

Actualización: noviembre 2007

Las variables que se usan en las operaciones de consulta de Language-Integrated Query (LINQ) tienen establecimiento inflexible de tipos y deben ser compatibles entre sí. Los tipos seguros se usan en el origen de datos, en la propia consulta y en la ejecución de la consulta. La ilustración siguiente identifica los términos que se utilizan para describir una consulta LINQ. Para obtener más información sobre las partes de una consulta, vea Operaciones básicas de consulta (Visual Basic).

Partes de una consulta LINQ

El tipo de la variable de rango de la consulta debe ser compatible con el tipo de los elementos del origen de datos. El tipo de la variable de consulta debe ser compatible con el elemento de secuencia definido en la cláusula Select. Finalmente, el tipo de los elementos de secuencia también debe ser compatible con el tipo de la variable de control del bucle que se utiliza en la instrucción For Each que ejecuta la consulta. Este establecimiento inflexible de tipos facilita la identificación de los errores de tipos en tiempo de compilación.

Visual Basic 2008 simplifica el establecimiento inflexible de tipos al implementar la inferencia de tipo de variable local, lo que también se conoce como tipo implícito. Esta característica se utiliza en el ejemplo anterior y, como observará, se utiliza en los ejemplos y la documentación de LINQ. En Visual Basic, la inferencia de tipo de variable local se consigue simplemente utilizando una instrucción Dim sin una cláusula As. En el ejemplo siguiente, city tiene establecimiento inflexible de tipos como cadena.

Dim city = "Seattle"
Nota:

La inferencia de tipo de variable local sólo funciona cuando Option Infer se establece en On. Para obtener más información, consulte Option Infer (Instrucción).

Sin embargo, aun cuando se utiliza la inferencia de tipo de variable local en una consulta, las mismas relaciones de tipo se encuentran entre las variables del origen de datos, la variable de consulta y el bucle de ejecución de la consulta. Es útil conocer los fundamentos de estas relaciones de tipos para escribir consultas LINQ o trabajar con los ejemplos y ejemplos de código de la documentación.

Consultas que devuelven elementos completos de los datos de origen

En el ejemplo siguiente se muestra una operación de consulta LINQ que devuelve una secuencia de elementos seleccionados de los datos de origen. El origen, names, contiene una matriz de cadenas y el resultado de la consulta es una secuencia que contiene cadenas que empiezan por la letra M.

Dim names = New String() {"John", "Rick", "Maggie", "Mary"}
Dim mNames = From name In names _
             Where name.IndexOf("M") = 0 _
             Select name

For Each nm In mNames
    Console.WriteLine(nm)
Next

Es equivalente al código siguiente, pero es mucho más corto y más fácil de escribir. En Visual Basic, se prefiere la inferencia de tipo de variable local en las consultas.

Dim names2() As String = {"John", "Rick", "Maggie", "Mary"}
Dim mNames2 As IEnumerable(Of String) = _
    From name As String In names _
    Where name.IndexOf("M") = 0 _
    Select name

For Each nm As String In mNames
    Console.WriteLine(nm)
Next

En los dos ejemplos de código anteriores existen las siguientes relaciones, se determinen los tipos de forma implícita o explícita.

  1. El tipo de los elementos del origen de datos, names, es el tipo de la variable de rango, name, en la consulta.

  2. El tipo de objeto seleccionado, name, determina el tipo de la variable de consulta, mNames. Aquí name es una cadena, por lo que la variable de consulta es IEnumerable(Of String) en Visual Basic.

  3. La consulta definida en mNames se ejecuta en el bucle For Each El bucle recorre en iteración el resultado de ejecutar la consulta. Dado que mNames, cuando se ejecuta, devuelve una secuencia de cadenas, la variable de iteración del bucle, nm, también es una cadena.

Consultas que devuelven un campo de los elementos seleccionados

En el ejemplo siguiente se muestra una operación de consulta LINQ to SQL que devuelve una secuencia que contiene sólo una parte de cada elemento seleccionado del origen de datos. La consulta utiliza una colección de objetos Customer como origen de datos y proyecta sólo la propiedad Name en el resultado. Dado que el nombre del cliente es una cadena, la consulta genera una secuencia de cadenas como resultado.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim custNames = From cust In customers _
                Where cust.City = "London" _
                Select cust.Name

For Each custName In custNames
    Console.WriteLine(custName)
Next

Las relaciones entre las variables son como las del ejemplo más sencillo.

  1. El tipo de los elementos del origen de datos, customers, es el tipo de la variable de rango, cust, en la consulta. En este ejemplo, ese tipo es Customer.

  2. La instrucción Select devuelve la propiedad Name de cada objeto Customer en lugar del objeto completo. Dado que Name es una cadena, la variable de consulta, custNames, será de nuevo IEnumerable(Of String), no Customer.

  3. Dado que custNames representa una secuencia de cadenas, la variable de iteración del bucle For Each, custName, debe ser una cadena.

Sin la inferencia de tipo de variable local, el ejemplo anterior sería más difícil de escribir y de entender, como demuestra el ejemplo siguiente.

' Method GetTable returns a table of Customer objects.
 Dim customers As Table(Of Customer) = db.GetTable(Of Customer)()
 Dim custNames As IEnumerable(Of String) = _
     From cust As Customer In customers _
     Where cust.City = "London" _
     Select cust.Name

 For Each custName As String In custNames
     Console.WriteLine(custName)
 Next

Consultas que requieren tipos anónimos

En el ejemplo siguiente se muestra una situación más compleja. En el ejemplo anterior, no era apropiado especificar explícitamente los tipos de todas las variables. En este ejemplo, no se puede. En lugar de seleccionar los elementos Customer completos del origen de datos o un campo único de cada elemento, la cláusula Select de esta consulta devuelve dos propiedades del objeto Customer original: Name y City. Como respuesta a la cláusula Select, el compilador define un tipo anónimo que contiene esas dos propiedades. El resultado de ejecutar nameCityQuery en el bucle For Each es una colección de instancias del nuevo tipo anónimo. Dado que el tipo anónimo no tiene ningún nombre utilizable, no puede especificar explícitamente el tipo de nameCityQuery o custInfo. Es decir, con un tipo anónimo, no hay ningún nombre de tipo que se pueda utilizar en lugar de String en IEnumerable(Of String). Para obtener más información, consulte Tipos anónimos.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim nameCityQuery = From cust In customers _
                    Where cust.City = "London" _
                    Select cust.Name, cust.City

For Each custInfo In nameCityQuery
    Console.WriteLine(custInfo.Name)
Next

Aunque no es posible especificar los tipos de todas las variables en el ejemplo anterior, las relaciones siguen siendo las mismas.

  1. El tipo de los elementos del origen de datos es de nuevo el tipo de la variable de rango de la consulta. En este ejemplo, cust es una instancia de Customer.

  2. Dado que la instrucción Select genera un tipo anónimo, el tipo de la variable de consulta, nameCityQuery, debe declararse implícitamente como un tipo anónimo. Un tipo anónimo no tiene un nombre utilizable y, por consiguiente, no se puede especificar explícitamente.

  3. El tipo de la variable de iteración del bucle For Each es el tipo anónimo creado en el paso 2. Dado que no tiene un nombre utilizable, el tipo de la variable de iteración del bucle se debe determinar implícitamente.

Vea también

Conceptos

Tipos anónimos

Inferencia de tipo de variable local

Introducción a LINQ en Visual Basic

Otros recursos

Introducción a LINQ en Visual Basic

LINQ en Visual Basic

Consultas (Visual Basic)