Compartir a través de


Introducción a LINQ en Visual Basic

Language-Integrated Query (LINQ) agrega funcionalidades de consulta a Visual Basic y proporciona funcionalidades sencillas y eficaces cuando se trabaja con todo tipo de datos. En lugar de enviar una consulta a una base de datos que se va a procesar o trabajar con una sintaxis de consulta diferente para cada tipo de datos que está buscando, LINQ presenta consultas como parte del lenguaje visual Basic. Usa una sintaxis unificada independientemente del tipo de datos.

LINQ permite consultar datos de una base de datos de SQL Server, XML, matrices y colecciones en memoria, ADO.NET conjuntos de datos o cualquier otro origen de datos remoto o local que admita LINQ. Puede hacer todo esto con 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 admiten IntelliSense, lo que permite escribir código más rápido y detectar errores en las consultas en tiempo de compilación en lugar de en tiempo de ejecución. Las consultas LINQ se pueden usar como 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 ejemplo de código siguiente se muestra una consulta LINQ que devuelve una lista de clientes de una colección y las agrupa en función de 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 en la sección Estructura de una consulta LINQ , incluya el código siguiente, 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. Al escribir una consulta LINQ, el proveedor toma esa consulta y la traduce en comandos que el origen de datos podrá ejecutar. El proveedor también convierte los datos del origen en los objetos que componen el resultado de la consulta. Por último, convierte objetos en datos al enviar actualizaciones al origen de datos.

Visual Basic incluye los siguientes proveedores LINQ.

Proveedor Descripción
LINQ to Objects (LINQ para Objetos) El proveedor LINQ to Objects permite consultar colecciones y matrices en memoria. Si un objeto admite la IEnumerable interfaz o IEnumerable<T> , el proveedor LINQ to Objects le permite consultarlo.

Puede habilitar el proveedor LINQ to Objects importando el System.Linq espacio de nombres, que se importa de forma 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 to SQL El proveedor LINQ to SQL permite consultar y modificar datos en una base de datos de SQL Server. Esto facilita la asignación del modelo de objetos de una aplicación a las tablas y objetos de una base de datos.

Visual Basic facilita el trabajo con LINQ to SQL mediante la inclusión del Diseñador relacional de objetos (O/R Designer). Este diseñador se utiliza para crear un modelo de objetos en una aplicación que mapea a objetos de una base de datos. El Diseñador de O/R también proporciona funcionalidad para asignar procedimientos almacenados y funciones al DataContext objeto, que administra la comunicación con la base de datos y almacena el estado de las comprobaciones de simultaneidad optimistas.

Para obtener más información sobre el proveedor LINQ to SQL, consulte LINQ to SQL. Para obtener más información sobre el Diseñador relacional de objetos, vea LINQ to SQL Tools en Visual Studio.
LINQ to XML El proveedor LINQ to XML permite consultar y modificar XML. Puede modificar XML en memoria o puede cargar XML desde y guardar XML en un archivo.

Además, el proveedor LINQ to XML habilita literales XML y propiedades del 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 datos en un conjunto de datos de ADO.NET. Puede agregar la eficacia de LINQ a las aplicaciones que usan conjuntos de datos para simplificar y ampliar sus funcionalidades para consultar, agregar y actualizar los datos del conjunto de datos.

Para más información, vea LINQ to DataSet.

Estructura de una consulta LINQ

Una consulta LINQ, a menudo denominada 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 puede incluir instrucciones para ordenar, filtrar, agrupar y combinar, o cálculos que se aplicarán a los datos de origen. La sintaxis de la expresión de consulta es similar a la sintaxis de SQL; por lo tanto, es posible que encuentre gran parte de la sintaxis familiar.

Una expresión de consulta comienza con una From cláusula . Esta cláusula identifica los datos de origen de una consulta y las variables que se usan para hacer referencia a cada elemento de los datos de origen individualmente. Estas variables se denominan variables de rango o variables de iteración. La From cláusula es necesaria para una consulta, excepto para Aggregate las consultas, donde la From cláusula es opcional. Una vez que se identifican el ámbito y el origen de la consulta en las cláusulas From o Aggregate, puede incluir cualquier combinación de cláusulas para refinar la consulta. Para obtener más información sobre las cláusulas de consulta, vea Operadores de consulta LINQ de Visual Basic más adelante en este tema. Por ejemplo, la consulta siguiente identifica una colección de orígenes de datos del cliente como la customers variable 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 se vuelve mucho más eficaz cuando se agregan más cláusulas de consulta para refinar el resultado. Por ejemplo, puede agregar una Where cláusula para filtrar el resultado por uno o varios valores. Las expresiones de consulta son una sola línea de código; Simplemente puede anexar cláusulas de consulta adicionales al final de la consulta. Puede dividir una consulta en varias líneas de texto para mejorar la legibilidad mediante el carácter de continuación de línea de subrayado (_). En el ejemplo de código siguiente se muestra un ejemplo de una consulta que incluye una Where cláusula .

Dim queryResults = From cust In customers
                   Where cust.Country = "Canada"

Otra cláusula de consulta eficaz es la Select cláusula , que permite devolver solo 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 tipos con nombre. Puede usar la Select cláusula para devolver solo un solo campo del origen de datos. Al hacerlo, el tipo de la colección devuelto es el tipo de ese campo único. También puede usar la Select cláusula 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 ejemplo de código siguiente se muestra una expresión de consulta que devuelve una colección de tipos anónimos que tienen 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 se pueden usar para combinar varios orígenes de datos y devolver un único resultado. Esto se puede hacer con una o varias From cláusulas, o mediante las Join cláusulas de consulta o Group Join . En el ejemplo de código siguiente se muestra una expresión de consulta que combina datos de cliente y pedido y devuelve una colección de tipos anónimos que contienen datos de cliente 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 usar la Group Join cláusula para crear un resultado de consulta jerárquico que contenga una colección de objetos de cliente. Cada objeto de cliente tiene una propiedad que contiene una colección de todos los pedidos de ese cliente. En el ejemplo de código siguiente se muestra una expresión de consulta que combina los datos de clientes y pedidos como resultado jerárquico y devuelve una colección de tipos anónimos. La consulta devuelve un tipo que incluye una CustomerOrders propiedad que contiene una colección de datos de pedido para el cliente. También incluye una OrderTotal propiedad 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 usar para crear expresiones de consulta eficaces. En la siguiente sección de este tema se describen las distintas cláusulas de consulta que puede incluir en una expresión de consulta. Para obtener más información sobre las cláusulas de consulta de Visual Basic, consulte Consultas.

Operadores de consulta LINQ de Visual Basic

Las clases del System.Linq espacio de nombres y los otros espacios de nombres que admiten consultas LINQ incluyen métodos a los que se puede llamar para crear y refinar consultas en función de las necesidades de la aplicación. Visual Basic incluye palabras clave para las siguientes cláusulas de consulta comunes. Para obtener más información sobre las cláusulas de consulta de Visual Basic, consulte Consultas.

Cláusula From

Se requiere una From cláusula o una Aggregate cláusula para iniciar una consulta. Una From cláusula especifica una colección de origen y una variable de iteración para 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. Una 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 Select cláusula , las variables de iteración de la consulta constan de las variables de iteración especificadas por la From cláusula o Aggregate .

Cláusula WHERE

Opcional. Una 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. Una 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

Cláusula de Unión

Opcional. Una Join cláusula combina dos colecciones en una sola colección. 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. Una Group By cláusula agrupa los elementos de un resultado de 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

Cláusula de Unión de Grupos

Opcional. Una 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

Cláusula de Agregación

Se requiere una Aggregate cláusula o una From cláusula para iniciar una consulta. Una Aggregate cláusula aplica una o varias funciones de agregado a una colección. Por ejemplo, puede usar la Aggregate cláusula para calcular una suma de todos los elementos devueltos por una consulta, como hace el ejemplo siguiente.

' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
                 Into Sum(order.Amount)

También puede usar la Aggregate cláusula para modificar una consulta. Por ejemplo, puede usar la Aggregate cláusula 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. Una 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

Cláusula distinta

Opcional. Una Distinct cláusula 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

Cláusula de omisión

Opcional. Una Skip cláusula omite un número especificado de elementos de una colección y, a continuación, 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. Una Skip While cláusula omite los elementos de una colección siempre que una condición especificada sea true y, a continuación, 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. Una Take cláusula devuelve un número especificado de elementos contiguos desde el inicio de una colección. Por ejemplo:

' Returns the first 10 customers.
Dim customerList = From cust In customers
                   Take 10

Take While (cláusula)

Opcional. Una Take While cláusula incluye elementos de una colección siempre que una condición especificada sea true y omita 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 enumerables y consultables proporcionados por LINQ. Puede usar estas funcionalidades adicionales llamando a un operador de consulta determinado en el resultado de una expresión de consulta. Por ejemplo, en el ejemplo siguiente se usa el Enumerable.Union método para combinar los resultados de dos consultas en un resultado de consulta. Usa el Enumerable.ToList método 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 más información sobre las funcionalidades adicionales de LINQ, consulte Información general sobre operadores de consulta estándar.

Conexión a una base de datos mediante LINQ to SQL

En Visual Basic, identificará los objetos de base de datos de SQL Server, como tablas, vistas y procedimientos almacenados, a los que desea acceder mediante un archivo LINQ to SQL. Un archivo LINQ to SQL tiene una extensión de .dbml.

Cuando tenga una conexión válida a una base de datos de SQL Server, puede agregar una plantilla de elemento LINQ to SQL Classes al proyecto. Se mostrará el Diseñador relacional de objetos (diseñador de O/R). El Diseñador de O/R permite arrastrar los elementos que desea acceder en su código desde el Explorador de servidores/ y el Explorador de bases de datos a la superficie del diseñador. El archivo LINQ to SQL agrega un DataContext objeto al proyecto. Este objeto incluye propiedades y colecciones para las tablas y vistas a las que desea tener acceso y métodos para los procedimientos almacenados a los que desea llamar. Después de guardar los cambios en el archivo LINQ to SQL (.dbml), puede acceder a estos objetos en el código haciendo referencia al DataContext objeto definido por el Diseñador de O/R. El DataContext objeto del proyecto se denomina en función del nombre del archivo LINQ to SQL. Por ejemplo, un archivo LINQ to SQL denominado Northwind.dbml creará un DataContext objeto denominado NorthwindDataContext.

Para obtener ejemplos con instrucciones paso a paso, vea Cómo: Consultar una base de datos y Cómo: Llamar a un procedimiento almacenado.

Características de Visual Basic que admiten LINQ

Visual Basic incluye otras características importantes que simplifican el uso de LINQ y reducen la cantidad de código que debe escribir para realizar consultas LINQ. Estos incluyen lo siguiente:

  • 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 permitir que el compilador infiere el tipo en función del resultado de la consulta.

  • Métodos de extensión, que permiten ampliar un tipo existente con sus propios métodos sin modificar el propio tipo.

Para obtener más información, vea Características de Visual Basic que admiten LINQ.

Ejecución de consultas aplazada e inmediata

La ejecución de consultas es independiente de la creación de una consulta. Una vez creada una consulta, su ejecución se desencadena mediante un mecanismo independiente. Una consulta se puede ejecutar tan pronto como se define (ejecución inmediata), o bien se puede almacenar la definición y la consulta se puede ejecutar más adelante (ejecución diferida).

De forma predeterminada, al crear una consulta, la propia consulta no se ejecuta inmediatamente. En su lugar, la definición de consulta se almacena en la variable que se usa 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 en un For…Next bucle, se ejecuta la consulta. Este proceso se conoce como ejecución diferida.

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, Mino Max. Para obtener más información sobre las funciones de agregado, vea Cláusula aggregate.

El uso de los ToList métodos o ToArray también forzará la ejecución inmediata. Esto puede ser útil cuando desea ejecutar la consulta inmediatamente y almacenar en caché los resultados. Para obtener más información sobre estos métodos, vea Convertir tipos de datos.

Para obtener más información sobre la ejecución de consultas, consulte Escritura de la primera consulta LINQ.

XML en Visual Basic

Las características XML de Visual Basic incluyen literales XML y propiedades del eje XML, que permiten crear, acceder, consultar y modificar XML fácilmente en el código. Los literales XML 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 ejemplo de código siguiente se muestra cómo crear un elemento XML, obtener acceso 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.

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 que están disponibles en Visual Basic.
LINQ (Language Integrated Query) Incluye información general, instrucciones de programación y ejemplos para LINQ.
LINQ to SQL Incluye información general, instrucciones de programación y ejemplos para LINQ to SQL.
LINQ to Objects Incluye información general, instrucciones de programación y ejemplos para LINQ to Objects.
LINQ to ADO.NET (página Portal) Incluye vínculos a información general, instrucciones de programación y ejemplos para LINQ to ADO.NET.
LINQ to XML Incluye información general, instrucciones de programación y ejemplos para LINQ to XML.

Temas de procedimientos y tutoriales

Procedimiento para consultar una base de datos

Cómo: Llamar a un procedimiento almacenado

Cómo: Modificar datos en una base de datos

Procedimiento: Combinar datos con combinaciones

Procedimiento para ordenar los resultados de la consulta

Cómo: Filtrar los resultados de la consulta

Cómo: Recuento, suma o promedio de datos

Cómo: Buscar el valor mínimo o máximo en un resultado de consulta

Cómo: Asignar procedimientos almacenados para realizar actualizaciones, inserciones y eliminaciones (Diseñador de O/R)

Capítulo 17: LINQ en programación de Visual Basic 2008

Consulte también