You are on page 1of 6

Escribir la primera consulta con LINQ (Visual Basic)

Una consulta es una expresin que recupera datos de un origen de datos. Las consultas se
expresan en un lenguaje de consultas dedicado. A lo largo del tiempo se han ido
desarrollando lenguajes diferentes para los distintos tipos de orgenes de datos, como SQL
para las bases de datos relacionales y XQuery para XML. De esta manera, el desarrollador
de aplicaciones debe aprender un nuevo lenguaje de consultas para cada tipo de origen de
datos o formato de datos admitido.
Language-Integrated Query (LINQ) simplifica esta situacin al proporcionar un modelo
coherente para trabajar con los datos de varios formatos y orgenes de datos. En una
consulta LINQ, siempre se trabaja con objetos. Se utilizan los mismos modelos de
codificacin bsicos para consultar y transformar los datos de documentos XML, bases de
datos de SQL, conjuntos de datos y entidades de ADO.NET, colecciones de .NET
Framework y cualquier otro formato u origen de datos para el que haya un proveedor LINQ
disponible. En este documento se describen las tres fases para crear y utilizar consultas
LINQ bsicas.
Las tres etapas de una operacin de consulta

Las operaciones de consulta LINQ se componen de tres acciones:
1. Obtencin de uno o varios orgenes de datos.
2. Creacin de la consulta.
3. Ejecucin de la consulta.
En LINQ, la ejecucin y la creacin de una consulta son operaciones distintas. Por el
simple hecho de crear una consulta, no se recuperan datos. Este punto se analiza con ms
detalle ms adelante, en este mismo tema.
En el ejemplo siguiente se muestran las tres partes de una operacin de consulta. En el
ejemplo se utiliza una matriz de enteros como origen de datos, cmodo a efectos de
demostracin. Sin embargo, los mismos conceptos tambin se aplican a otros orgenes de
datos.
VB
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers _
Where num Mod 2 = 0 _
Select num

' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next


Resultado:
0 2 4 6
El origen de datos

Dado que el origen de datos del ejemplo anterior es una matriz, se admite implcitamente la
interfaz genrica IEnumerable(Of T). Es este hecho lo que permite utilizar una matriz como
origen de datos para una consulta LINQ. Los tipos que admiten IEnumerable(Of T) o una
interfaz derivada, como la genrica IQueryable(Of T), se conocen como tipos que se
pueden consultar.
Como tipo que se puede consultar implcitamente, la matriz no requiere modificaciones ni
un tratamiento especial para actuar como origen de datos LINQ. Lo mismo sucede con
cualquier tipo de coleccin que admita IEnumerable(Of T), incluidas las genricas List(Of
T), Dictionary(Of TKey, TValue) y otras clases de la biblioteca de clases de .NET
Framework.
Si los datos de origen todava no implementan IEnumerable(Of T), se requiere un
proveedor LINQ para implementar la funcionalidad de los operadores de consulta estndar
para ese origen de datos. Por ejemplo, LINQ to XML controla el trabajo de cargar un
documento XML en un tipo XElement que se pueda consultar, como se muestra en el
ejemplo siguiente. Para obtener ms informacin sobre los operadores de consulta estndar,
vea Informacin general sobre operadores de consulta estndar.
VB

' Create a data source from an XML document.
Dim contacts As XElement = XElement.Load("c:\myContactList.xml")


Con LINQ to SQL, primero se crea una asignacin relacional de objetos en tiempo de
diseo, ya sea manualmente o mediante el Diseador relacional de objetos (Diseador
R/O). Despus, se escriben las consultas en los objetos y, en tiempo de ejecucin, LINQ to
SQL controla la comunicacin con la base de datos. En el ejemplo siguiente, customers
representa una tabla concreta de la base de datos y Table(Of TEntity) admite la interfaz
genrica IQueryable(Of T).
VB
' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)
Para obtener ms informacin sobre cmo crear tipos de orgenes de datos especficos,
consulte la documentacin de los distintos proveedores LINQ. (Para obtener una lista de
estos proveedores, vea Language-Integrated Query (LINQ).) La regla bsica es simple: un
origen de datos LINQ es cualquier objeto que admite la interfaz genrica IEnumerable(Of
T) o una interfaz que herede de ella.
Nota:
Tambin se pueden utilizar tipos como ArrayList, que admite la interfaz no genrica
IEnumerable, como orgenes de datos LINQ. Para obtener un ejemplo donde se
usa ArrayList, vea Cmo: Consultar un objeto ArrayList con LINQ.
La consulta

En la consulta se especifica qu informacin se desea recuperar del origen o de los orgenes
de datos. Tambin tiene la opcin de especificar cmo se debera ordenar, agrupar o
estructurar esa informacin antes de devolverse. Para habilitar la creacin de consultas,
Visual Basic incorpora nueva sintaxis de consulta en el lenguaje.
Cuando se ejecuta, la consulta del ejemplo siguiente devuelve todos los nmeros pares de
una matriz de enteros, numbers.
VB
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers _
Where num Mod 2 = 0 _
Select num

' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next


La expresin de consulta contiene tres clusulas: From, Where y Select. La funcin y el
propsito especficos de cada una de las clusulas de las expresiones de consulta se analiza
en Operaciones bsicas de consulta (Visual Basic). Para obtener ms informacin, consulte
Consultas (Visual Basic). Observe que en LINQ una definicin de consulta suele
almacenarse en una variable y se ejecuta despus. La variable de consulta,
como evensQuery en el ejemplo anterior, debe ser un tipo que se pueda consultar. El tipo de
evensQuery es IEnumerable(Of Integer), asignado por el compilador mediante la inferencia
de tipo de variable local.
Es importante recordar que la propia variable de consulta no realiza ninguna accin ni
devuelve datos. Slo almacena la definicin de la consulta. En el ejemplo anterior, es el
bucle For Each el que ejecuta la consulta.
Ejecucin de la consulta

La ejecucin de la consulta es proceso independiente de su creacin. La creacin de la
consulta la define, pero su ejecucin la desencadena un mecanismo diferente. Se puede
ejecutar un consulta en cuanto est definida (ejecucin inmediata), o se puede guardar la
definicin y ejecutar la consulta ms tarde (ejecucin diferida).
Ejecucin diferida
Una consulta LINQ tpica se parece a la del ejemplo anterior, en el que se define
evensQuery. En l se crea la consulta, pero no se ejecuta de inmediato. La definicin de la
consulta se almacena en la variable de consulta evensQuery. La consulta se ejecuta ms
adelante, normalmente mediante un bucle For Each, que devuelve una secuencia de valores,
o aplicando un operador de consulta estndar, como Count o Max. Este proceso se
denomina ejecucin diferida.
VB

' Query execution that results in a sequence of values.
For Each number In evensQuery
Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()


Para una secuencia de valores, se tiene acceso a los datos recuperados mediante la variable
de iteracin del bucle For Each (number en el ejemplo anterior). Dado que la variable de
consulta, evensQuery, contiene la definicin de la consulta en lugar de los resultados, puede
ejecutar una consulta tantas veces como desee, utilizando la variable de consulta. Por
ejemplo, podra tener una base de datos en su aplicacin que sea actualizada continuamente
por una aplicacin independiente. Despus de haber creado una consulta que recupere los
datos de esa base de datos, puede utilizar un bucle For Each para ejecutar la consulta una y
otra vez, recuperando en cada ocasin los datos ms recientes.
En el siguiente ejemplo se muestra cmo funciona la ejecucin diferida. Una vez definida
evensQuery2 y ejecutada con un bucle For Each, como en los ejemplos anteriores, algunos
elementos del origen de datos numbers cambian. A continuacin, un segundo bucle For
Each vuelve a ejecutar evensQuery2. Los resultados son diferentes la segunda vez, porque
el bucle For Each ejecuta la consulta otra vez, utilizando los nuevos valores de numbers.
VB

Dim numberArray() As Integer = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray _
Where num Mod 2 = 0 _
Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()


Resultado:
Evens in original array:
0 2 4 6
Evens in changed array:
0 10 2 22 8
Ejecucin inmediata
En la ejecucin diferida de consultas, la definicin de la consulta se almacena en una
variable de consulta para su posterior ejecucin. En la ejecucin inmediata, la consulta se
ejecuta en el momento de su definicin. La ejecucin se activa al aplicar un mtodo que
requiere acceso a los elementos individuales del resultado de la consulta. La ejecucin
inmediata se fuerza mediante el uso de uno de los operadores de consulta estndar que
devuelven valores nicos. Algunos ejemplos son Count, Max, Average y First. Estos
operadores de consulta estndar ejecutan la consulta en cuanto se aplican para calcular y
devolver un resultado singleton. Para obtener ms informacin sobre los operadores de
consulta estndar que devuelven valores nicos, vea Operaciones de agregacin,
Operaciones de elementos y Operaciones cuantificadoras.
La consulta siguiente devuelve un recuento de los nmeros pares de una matriz de enteros.
La definicin de la consulta no se guarda y numEvens es un Integer simple.
VB
Dim numEvens = (From num In numbers _
Where num Mod 2 = 0 _
Select num).Count()


Se puede conseguir el mismo resultado utilizando el mtodo Aggregate.
VB
Dim numEvensAgg = Aggregate num In numbers _
Where num Mod 2 = 0 _
Select num _
Into Count()


Tambin puede forzar la ejecucin de una consulta llamando al mtodo ToList o ToArray
en una consulta (ejecucin inmediata) o variable de consulta (ejecucin diferida), como se
muestra en el cdigo siguiente.
VB
' Immediate execution.
Dim evensList = (From num In numbers _
Where num Mod 2 = 0 _
Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers _
Where num Mod 2 = 0 _
Select num
' . . .
Dim evensArray = evensQuery.ToArray()


En los ejemplos anteriores, evensQuery3 es una variable de consulta, pero evensList es una
lista y evensArray es una matriz.
El uso de ToList o ToArray para forzar la ejecucin inmediata es especialmente til cuando
se desea ejecutar la consulta inmediatamente y almacenar los resultados en memoria cach
en un objeto de coleccin nico. Para obtener ms informacin sobre estos mtodos, vea
Convertir tipos de datos.
Tambin puede provocar la ejecucin de una consulta mediante el uso de un mtodo
IEnumerable, como GetEnumerator (Mtodo, objeto Collection).

You might also like