stringtranslate.com

Consulta integrada de lenguaje

Language Integrated Query ( LINQ , pronunciado "enlace") es un componente de Microsoft .NET Framework que agrega capacidades nativas de consulta de datos a los lenguajes .NET , lanzado originalmente como una parte importante de .NET Framework 3.5 en 2007.

LINQ amplía el lenguaje mediante la adición de expresiones de consulta , que son similares a sentencias SQL y se pueden utilizar para extraer y procesar datos de forma conveniente desde matrices , clases enumerables , documentos XML , bases de datos relacionales y fuentes de datos de terceros. Otros usos, que utilizan expresiones de consulta como marco general para componer cálculos arbitrarios de forma legible, incluyen la construcción de controladores de eventos [1] o analizadores monádicos . [2] También define un conjunto de nombres de métodos (llamados operadores de consulta estándar u operadores de secuencia estándar ), junto con las reglas de traducción utilizadas por el compilador para traducir expresiones de sintaxis de consulta en expresiones que utilizan un estilo fluido (llamado sintaxis de método por Microsoft) con estos nombres de métodos, expresiones lambda y tipos anónimos .

Existen puertos de LINQ para PHP (PHPLinq), JavaScript (linq.js), TypeScript (linq.ts) y ActionScript (ActionLinq), aunque ninguno es estrictamente equivalente a LINQ en los lenguajes inspirados en .NET C#, F# y VB.NET. (donde es parte del lenguaje, no una biblioteca externa, y donde a menudo aborda una gama más amplia de necesidades). [ cita necesaria ]

Arquitectura de LINQ en .NET Framework

API de operador de consulta estándar

A continuación, las descripciones de los operadores se basan en la aplicación del trabajo con colecciones. Muchos de los operadores toman otras funciones como argumentos. Estas funciones pueden proporcionarse en forma de método con nombre o función anónima.

El conjunto de operadores de consulta definidos por LINQ se expone al usuario como API del operador de consulta estándar (SQO) . Los operadores de consulta soportados por la API son: [3]

Seleccionar

El operador Select realiza una proyección sobre la colección para seleccionar aspectos interesantes de los elementos. El usuario proporciona una función arbitraria, en forma de expresión lambda o con nombre , que proyecta los miembros de datos. La función se pasa al operador como delegado .

Dónde

El operador Where permite la definición de un conjunto de reglas de predicado que se evalúan para cada objeto de la colección, mientras que los objetos que no coinciden con la regla se filtran. El predicado se proporciona al operador como delegado.

SeleccionarMuchos

Para una asignación proporcionada por el usuario de elementos de colección a colecciones, semánticamente se realizan dos pasos. Primero, cada elemento se asigna a su colección correspondiente. En segundo lugar, el resultado del primer paso se aplana en un nivel. Nota: Tanto Select como Where se pueden implementar en términos de SelectMany, siempre que haya colecciones únicas y vacías disponibles. Las reglas de traducción mencionadas anteriormente aún hacen obligatorio que un proveedor de LINQ proporcione los otros dos operadores.

Suma / Mín / Máx / Promedio

Opcionalmente, estos operadores toman una función que recupera un determinado valor numérico de cada elemento de la colección y lo utiliza para encontrar los valores suma, mínimo, máximo o promedio de todos los elementos de la colección, respectivamente. Las versiones sobrecargadas no tienen ninguna función y actúan como si la identidad se proporcionara como lambda.

Agregar

Una suma generalizada/mín/máx. Este operador toma una función que especifica cómo se combinan dos valores para formar un resultado intermedio o final. Opcionalmente, se puede proporcionar un valor inicial, lo que permite que el tipo de resultado de la agregación sea arbitrario. Además, se puede proporcionar una función de finalización que lleve el resultado de la agregación a otro valor más.

Unirse / GrupoUnirse
El operador Join realiza una unión interna en dos colecciones, basándose en claves coincidentes para los objetos de cada colección. Toma dos funciones como delegados, una para cada colección, que ejecuta en cada objeto de la colección para extraer la clave del objeto. También se necesita otro delegado en el que el usuario especifica qué elementos de datos, de los dos elementos coincidentes, deben usarse para crear el objeto resultante. El operador GroupJoin realiza una unión de grupo . Al igual que el operador Seleccionar, los resultados de una unión son instancias de una clase diferente, con todos los miembros de datos de ambos tipos de objetos de origen, o un subconjunto de ellos.
Tomar / Tomar Mientras
El operador Take selecciona los primeros n objetos de una colección, mientras que el operador TakeWhile, que toma un predicado, selecciona aquellos objetos que coinciden con el predicado (deteniéndose en el primer objeto que no coincide).
Saltar / Saltar Mientras
Los operadores Skip y SkipWhile son complementos de Take y TakeWhile: omiten los primeros n objetos de una colección o aquellos objetos que coinciden con un predicado (para el caso de SkipWhile).
De tipo
El operador OfType se utiliza para seleccionar los elementos de un determinado tipo.
Concat
El operador Concat concatena dos colecciones.
Ordenar por / luego por
El operador OrderBy se utiliza para especificar el orden principal de los elementos de una colección según alguna clave. El orden predeterminado es ascendente; para invertir el orden, se debe utilizar el operador OrderByDescending . ThenBy y ThenByDescending especifican el orden posterior de los elementos. La función para extraer el valor clave del objeto la especifica el usuario como delegado.
Contrarrestar
El operador Inverso invierte una colección.
Agrupar por
El operador GroupBy toma una función que extrae un valor clave y devuelve una colección de IGrouping<Key, Values>objetos, para cada valor clave distinto. Luego, los IGroupingobjetos se pueden usar para enumerar todos los objetos para un valor clave particular.
Distinto
El operador Distinto elimina instancias duplicadas de un objeto de una colección. Una sobrecarga del operador toma un objeto comparador de igualdad que define los criterios de distinción.
Unión / Intersección / Excepto
Estos operadores se utilizan para realizar una operación de unión , intersección y diferencia en dos secuencias, respectivamente. Cada uno tiene una sobrecarga que toma un objeto comparador de igualdad que define los criterios para la igualdad de elementos.
SecuenciaIgual
El operador SequenceEqual determina si todos los elementos de dos colecciones son iguales y están en el mismo orden.
Primero/PrimeroOPorDefecto/Último/ÚltimoOPorDefecto
Estos operadores toman un predicado. El operador Primero devuelve el primer elemento para el cual el predicado produce verdadero o, si nada coincide, genera una excepción. El operador FirstOrDefault es como el operador First excepto que devuelve el valor predeterminado para el tipo de elemento (normalmente una referencia nula) en caso de que nada coincida con el predicado. El último operador recupera el último elemento que coincide con el predicado o genera una excepción en caso de que nada coincida. LastOrDefault devuelve el valor del elemento predeterminado si nada coincide.
Soltero
El operador único toma un predicado y devuelve el elemento que coincide con el predicado. Se produce una excepción si ninguno o más de un elemento coincide con el predicado.
Único o predeterminado
El operador SingleOrDefault toma un predicado y devuelve el elemento que coincide con el predicado. Si más de un elemento coincide con el predicado, se lanza una excepción. Si ningún elemento coincide con el predicado, se devuelve un valor predeterminado.
elementoen
El operador ElementAt recupera el elemento en un índice determinado de la colección.
Cualquiera/Todos
El operador Cualquier comprueba si hay elementos en la colección que coincidan con el predicado. No selecciona el elemento, pero devuelve verdadero si al menos un elemento coincide. Una invocación de any sin predicado devuelve verdadero si la colección no está vacía. El operador Todo devuelve verdadero si todos los elementos coinciden con el predicado.
Contiene
El operador Contiene comprueba si la colección contiene un elemento determinado.
Contar
El operador Count cuenta el número de elementos de la colección dada. Una sobrecarga que toma un predicado cuenta el número de elementos que coinciden con el predicado.

La API del operador de consulta estándar también especifica ciertos operadores que convierten una colección en otro tipo: [3]

Extensiones de idioma

Si bien LINQ se implementa principalmente como una biblioteca para .NET Framework 3.5, también define extensiones de lenguaje opcionales que hacen de las consultas una construcción de lenguaje de primera clase y proporcionan azúcar sintáctico para escribir consultas. Estas extensiones de lenguaje se implementaron inicialmente en C# 3.0, [5] : 75  VB 9.0 , F# [6] y Oxygene , y otros lenguajes como Nemerle han anunciado soporte preliminar. Las extensiones de idioma incluyen: [7]

Por ejemplo, en la consulta para seleccionar todos los objetos de una colección con SomePropertymenos de 10,

var resultados = de c en SomeCollection donde c . AlgunaPropiedad < 10 seleccione nuevo { c . Alguna propiedad , c . Otra propiedad };              foreach ( var resultado en resultados ) { Console . WriteLine ( resultado ); }     

El compilador infiere todos los tipos de variables result , c y results de acuerdo con las firmas de los métodos finalmente utilizados. La base para elegir los métodos está formada por el resultado de la traducción sin expresión de la consulta.

var resultados = AlgunaColección . Donde ( c => c . AlgunaPropiedad < 10 ) . Seleccione ( c => nuevo { c . AlgunaPropiedad , c . OtraPropiedad });             resultados . ForEach ( x => { Consola . WriteLine ( x . ToString ());})  

Proveedores LINQ

La especificación C#3.0 define un patrón de expresión de consulta junto con reglas de traducción de una expresión LINQ a una expresión en un subconjunto de C# 3.0 sin expresiones LINQ. La traducción así definida en realidad no tiene tipo, lo que, además de que las expresiones lambda se pueden interpretar como delegados o árboles de expresión, permite un gran grado de flexibilidad para las bibliotecas que deseen exponer partes de su interfaz como cláusulas de expresión LINQ. Por ejemplo, LINQ to Objects funciona con IEnumerable<T>s y con delegados, mientras que LINQ to SQL utiliza árboles de expresión.

Los árboles de expresión son el núcleo del mecanismo de extensibilidad de LINQ, mediante el cual LINQ se puede adaptar a muchas fuentes de datos. Los árboles de expresión se entregan a los proveedores LINQ, que son implementaciones específicas de la fuente de datos que adaptan las consultas LINQ para usarse con la fuente de datos. Si así lo desean, los proveedores LINQ analizan los árboles de expresión contenidos en una consulta para generar piezas esenciales necesarias para la ejecución de una consulta. Pueden ser fragmentos de SQL o cualquier otra representación de código completamente diferente como datos manipulables adicionales. LINQ viene con proveedores LINQ para colecciones de objetos en memoria, bases de datos de Microsoft SQL Server , conjuntos de datos ADO.NET y documentos XML. Estos diferentes proveedores definen las diferentes versiones de LINQ:

LINQ a objetos

El proveedor LINQ to Objects se utiliza para colecciones en memoria, utilizando el motor de ejecución de consultas local de LINQ. El código generado por este proveedor hace referencia a la implementación de los operadores de consulta estándar definidos en el Sequencepatrón y permite IEnumerable<T>consultar las colecciones localmente. La implementación actual de LINQ to Objects realiza comprobaciones de implementación de interfaz para permitir pruebas de membresía, recuentos y operaciones de búsqueda indexadas rápidas cuando son compatibles con el tipo de tiempo de ejecución de IEnumerable. [8] [9] [10]

LINQ a XML (anteriormente llamado XLINQ)

El proveedor LINQ to XML convierte un documento XML en una colección de XElementobjetos, que luego se consultan utilizando el motor de ejecución local que se proporciona como parte de la implementación del operador de consulta estándar. [11]

LINQ to SQL (anteriormente llamado DLINQ)

El proveedor LINQ to SQL permite utilizar LINQ para consultar bases de datos de Microsoft SQL Server , incluidas las bases de datos de SQL Server Compact . Dado que los datos de SQL Server pueden residir en un servidor remoto y que SQL Server tiene su propio motor de consultas, LINQ to SQL no utiliza el motor de consultas de LINQ. En su lugar, convierte una consulta LINQ en una consulta SQL que luego se envía a SQL Server para su procesamiento. [12] Sin embargo, dado que SQL Server almacena los datos como datos relacionales y LINQ trabaja con datos encapsulados en objetos, las dos representaciones deben asignarse entre sí. Por este motivo, LINQ to SQL también define un marco de mapeo. El mapeo se realiza definiendo clases que corresponden a las tablas de la base de datos y que contienen todas o un subconjunto de las columnas de la tabla como miembros de datos. [13] La correspondencia, junto con otros atributos del modelo relacional , como las claves primarias , se especifican mediante LINQ to atributos definidos por SQL . Por ejemplo,

[Table(Name="Clientes")] public class Cliente { [Column(IsPrimaryKey = true)] public int CustID ;       [Columna] cadena pública CustName ; }   

Esta definición de clase se asigna a una tabla denominada Customersy los dos miembros de datos corresponden a dos columnas. Las clases deben definirse antes de poder utilizar LINQ to SQL. Visual Studio 2008 incluye un diseñador de asignaciones que se puede utilizar para crear la asignación entre los esquemas de datos en el objeto y el dominio relacional. Puede crear automáticamente las clases correspondientes a partir de un esquema de base de datos , así como permitir la edición manual para crear una vista diferente utilizando solo un subconjunto de las tablas o columnas de una tabla. [13]

El mapeo se implementa mediante el DataContextque toma una cadena de conexión al servidor y se puede usar para generar un Table<T>donde T es el tipo al que se asignará la tabla de la base de datos. Encapsula Table<T>los datos en la tabla e implementa la IQueryable<T>interfaz, de modo que se crea el árbol de expresión, que maneja el proveedor LINQ to SQL. Convierte la consulta a T-SQL y recupera el conjunto de resultados del servidor de la base de datos. Dado que el procesamiento se realiza en el servidor de la base de datos, no se pueden utilizar métodos locales que no estén definidos como parte de las expresiones lambda que representan los predicados. Sin embargo, puede utilizar los procedimientos almacenados en el servidor. Se realiza un seguimiento de cualquier cambio en el conjunto de resultados y se puede enviar nuevamente al servidor de la base de datos. [13]

LINQ a conjuntos de datos

Dado que el proveedor LINQ to SQL (arriba) solo funciona con bases de datos de Microsoft SQL Server , para admitir cualquier base de datos genérica, LINQ también incluye LINQ to DataSets. Utiliza ADO.NET para manejar la comunicación con la base de datos. Una vez que los datos están en conjuntos de datos ADO.NET, LINQ to DataSets ejecuta consultas en estos conjuntos de datos. [14]

Actuación

Los usuarios no profesionales pueden tener dificultades con las sutilezas de las funciones y la sintaxis de LINQ to Objects . Los patrones ingenuos de implementación de LINQ pueden provocar una degradación catastrófica del rendimiento. [15] [16]

El rendimiento de LINQ to XML y LINQ to SQL en comparación con ADO.NET depende del caso de uso. [17] [18]

PLINQ

La versión 4 del marco .NET incluye PLINQ , o Parallel LINQ , un motor de ejecución paralela para consultas LINQ. Define la ParallelQuery<T>clase. Cualquier implementación de la IEnumerable<T>interfaz puede aprovechar el motor PLINQ llamando al AsParallel<T>(this IEnumerable<T>)método de extensión definido por la clase ParallelEnumerable en el espacio de nombres System.Linq del marco .NET. [19] El motor PLINQ puede ejecutar partes de una consulta simultáneamente en múltiples subprocesos, proporcionando resultados más rápidos. [20]

Idiomas predecesores

Muchos de los conceptos que introdujo LINQ se probaron originalmente en el proyecto de investigación de Microsoft , anteriormente conocido con los nombres en clave X# (X Sharp) y Xen . Pasó a llamarse Cω después de que se integrara Polyphonic C# , otro lenguaje de investigación basado en el cálculo de unión .

Cω intenta hacer que los almacenes de datos (como bases de datos y documentos XML ) sean accesibles con la misma facilidad y seguridad de tipos que los tipos tradicionales como cadenas y matrices . Muchas de estas ideas fueron heredadas de un proyecto de incubación anterior dentro del equipo XML de WebData llamado X# y Xen. Cω también incluye nuevas construcciones para soportar la programación concurrente ; Estas características se derivaron en gran medida del proyecto anterior Polyphonic C#. [21]

Disponible por primera vez en 2004 como una vista previa del compilador, las características de Cω fueron utilizadas posteriormente por Microsoft en la creación de las características de LINQ lanzadas en 2007 en .NET versión 3.5 [22]. Las construcciones de concurrencia también se han lanzado en una forma ligeramente modificada como una biblioteca. denominado Joins Concurrency Library , para C# y otros lenguajes .NET por Microsoft Research . [23]

Ver también

Referencias

  1. ^ "Marco de recetas".
  2. ^ "Combinadores de analizadores monádicos que utilizan C#3" . Consultado el 21 de noviembre de 2009 .
  3. ^ ab "Operadores de consulta estándar". Microsoft . Consultado el 30 de noviembre de 2007 .
  4. ^ "Clase enumerable". msdn . Microsoft . Consultado el 15 de febrero de 2014 .
  5. ^ ab plato, Jon. C# en profundidad . Manning. ISBN 978-1617294532.
  6. ^ "Expresiones de consulta (F#)". Documentos de Microsoft . Consultado el 19 de diciembre de 2012 .
  7. ^ "Marco LINQ" . Consultado el 30 de noviembre de 2007 .
  8. ^ "Enumerable.ElementAt" . Consultado el 7 de mayo de 2014 .
  9. ^ "Enumerable. Contiene" . Consultado el 7 de mayo de 2014 .
  10. ^ "Enumerable.Count" . Consultado el 7 de mayo de 2014 .
  11. ^ "Consulta integrada en lenguaje .NET para datos XML" . Consultado el 30 de noviembre de 2007 .
  12. ^ "LINQ a SQL". Archivado desde el original el 25 de enero de 2013 . Consultado el 30 de noviembre de 2007 .
  13. ^ abc "LINQ to SQL: consulta integrada en lenguaje .NET para datos relacionales" . Consultado el 30 de noviembre de 2007 .
  14. ^ "LINQ a conjuntos de datos". Archivado desde el original el 25 de enero de 2013 . Consultado el 30 de noviembre de 2007 .
  15. ^ Vider, chico (21 de diciembre de 2007). "Prueba de rendimiento de LINQ: mi primer proyecto de Visual Studio 2008" . Consultado el 8 de febrero de 2009 .
  16. ^ Parsons, Jared (2008). "Aumentar el rendimiento de las consultas LINQ". Red de desarrolladores de Microsoft . Consultado el 19 de marzo de 2014 . Si bien es cierto que LINQ es potente y muy eficiente, grandes conjuntos de datos aún pueden causar problemas de rendimiento inesperados.
  17. ^ Alva, Jaime (6 de agosto de 2010). "Posibles problemas de rendimiento con las recompilaciones de consultas LINQ compiladas". Red de desarrolladores de Microsoft . Consultado el 19 de marzo de 2014 . Al llamar a una consulta varias veces con Entity Framework, el enfoque recomendado es utilizar consultas LINQ compiladas. La compilación de una consulta da como resultado un impacto en el rendimiento la primera vez que usa la consulta, pero las llamadas posteriores se ejecutan mucho más rápido.
  18. ^ Kshitij, Pandey (25 de mayo de 2008). "Comparaciones de rendimiento de LinQ con SQL, ADO, C#" . Consultado el 8 de febrero de 2009 .
  19. ^ "Clase ParallelEnumerable" . Consultado el 7 de mayo de 2014 .
  20. ^ "Programación en la era de la concurrencia: programación concurrente con PFX" . Consultado el 16 de octubre de 2007 .
  21. ^ Eichert, Steve; Wooley, James B.; Marguerie, Fabrice (2008). LINQ en acción . Manning. págs. 56-57 (como se informa en el enlace de búsqueda de Google Books; el libro no tiene números de página). ISBN 9781638354628.
  22. ^ Conceptos detrás del lenguaje C# 3.0 | Artículos | TomasP.Net Archivado el 12 de febrero de 2007 en la Wayback Machine.
  23. ^ "La biblioteca de simultaneidad de uniones" . Consultado el 8 de junio de 2007 .

enlaces externos