Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Expresiones de consulta
Las expresiones de consulta usan una sintaxis declarativa similar a SQL o XQuery para consultar sobre System.Collections.Generic.IEnumerable<T> colecciones. En tiempo de compilación, la sintaxis de consulta se convierte en llamadas de método a la implementación de un proveedor LINQ de los métodos de consulta estándar. Las aplicaciones controlan los operadores de consulta estándar que están dentro del alcance especificando el espacio de nombres adecuado con la directiva using
. La siguiente expresión de consulta toma una matriz de cadenas, las agrupa según el primer carácter de la cadena y ordena los grupos.
var query = from str in stringArray
group str by str[0] into stringGroup
orderby stringGroup.Key
select stringGroup;
Variables con tipo implícito (var)
Puede usar el modificador var para indicar al compilador que infiera y asigne el tipo, como se muestra aquí:
var number = 5;
var name = "Virginia";
var query = from str in stringArray
where str[0] == 'm'
select str;
Las variables declaradas como var
están fuertemente tipadas, como las variables cuyo tipo se especifica explícitamente. El uso de var
permite crear tipos anónimos, pero solo para variables locales. Para obtener más información, vea Variables locales con tipo implícito.
Inicializadores de objeto y colección
Los inicializadores de objeto y colección permiten inicializar objetos sin llamar explícitamente a un constructor para el objeto. Los inicializadores se suelen usar en expresiones de consulta cuando proyectan los datos de origen en un nuevo tipo de datos. Suponiendo una clase denominada Customer
con propiedades públicas Name
y Phone
, el inicializador de objeto se puede usar como en el siguiente código.
var cust = new Customer { Name = "Mike", Phone = "555-1212" };
Continuando con su clase Customer
, supongamos que hay un origen de datos denominado IncomingOrders
y que, para cada pedido con un gran OrderSize
, desea crear un nuevo Customer
basado en ese pedido. Una consulta LINQ se puede ejecutar en este origen de datos y usar la inicialización de objetos para rellenar una colección:
var newLargeOrderCustomers = from o in IncomingOrders
where o.OrderSize > 5
select new Customer { Name = o.Name, Phone = o.Phone };
Es posible que el origen de datos tenga más propiedades definidas que la Customer
clase como OrderSize
, pero con la inicialización de objetos, los datos devueltos de la consulta se moldean en el tipo de datos deseado; se eligen los datos pertinentes para la clase. Como resultado, ahora tienes un System.Collections.Generic.IEnumerable<T> lleno de los nuevos elementos Customer
que querías. El ejemplo anterior también se puede escribir en la sintaxis del método de LINQ:
var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });
A partir de C# 12, puede usar una expresión de colección para inicializar una colección.
Para obtener más información, consulte:
- Inicializadores de objeto y colección
- Sintaxis de expresiones de consulta para operadores de consulta estándar
Tipos anónimos
El compilador crea un tipo anónimo. El nombre del tipo solo está disponible para el compilador. Los tipos anónimos proporcionan una manera cómoda de agrupar temporalmente un conjunto de propiedades en un resultado de consulta sin tener que definir un tipo con nombre independiente. Los tipos anónimos se inicializan con una nueva expresión y un inicializador de objeto, como se muestra aquí:
select new {name = cust.Name, phone = cust.Phone};
A partir de C# 7, puede usar tuplas para crear tipos sin nombre.
Métodos de extensión.
Un método de extensión es un método estático que se puede asociar a un tipo, de modo que se pueda llamar como si fuera un método de instancia en el tipo. Esta característica le permite, en efecto, agregar nuevos métodos a los tipos existentes sin modificarlos realmente. 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 implemente IEnumerable<T>.
Expresiones lambda
Una expresión lambda es una función en línea que usa el =>
operador para separar los parámetros de entrada del cuerpo de la función y que en tiempo de compilación se puede convertir en un delegado o en un árbol de expresión. En la programación LINQ, se producen expresiones lambda al realizar llamadas de método directo a los operadores de consulta estándar.
Expresiones como datos
Los objetos de consulta se pueden componer, lo que significa que puede devolver una consulta desde un método . Los objetos que representan consultas no almacenan la colección resultante, sino los pasos para generar los resultados cuando sea necesario. La ventaja de devolver objetos de consulta desde métodos es que se pueden componer o modificar todavía más. Por lo tanto, cualquier valor devuelto o out
parámetro de un método que devuelva una consulta también debe tener ese tipo. Si un método materializa una consulta en un tipo List<T> o Array concreto, devuelve los resultados de la consulta en lugar de la propia consulta. Una variable de consulta que se devuelve de un método todavía se puede componer o modificar.
En el ejemplo siguiente, el primer método QueryMethod1
devuelve una consulta como un valor devuelto y el segundo método QueryMethod2
devuelve una consulta como parámetro out
(returnQ
en el ejemplo). En ambos casos, es una consulta que se devuelve, no los resultados de la consulta.
IEnumerable<string> QueryMethod1(int[] ints) =>
from i in ints
where i > 4
select i.ToString();
void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
returnQ = from i in ints
where i < 4
select i.ToString();
int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
var myQuery1 = QueryMethod1(nums);
La consulta myQuery1
se ejecuta en el siguiente bucle foreach.
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}
Reste el puntero del mouse sobre myQuery1
para ver su tipo.
También puede ejecutar la consulta devuelta desde QueryMethod1
directamente, sin usar myQuery1
.
foreach (var s in QueryMethod1(nums))
{
Console.WriteLine(s);
}
Reste el puntero del mouse sobre la llamada a QueryMethod1
para ver su tipo de valor devuelto.
QueryMethod2
devuelve una consulta como el valor de su out
parámetro:
QueryMethod2(nums, out IEnumerable<string> myQuery2);
// Execute the returned query.
foreach (var s in myQuery2)
{
Console.WriteLine(s);
}
Puede modificar una consulta mediante la composición de la consulta. En este caso, el objeto de consulta anterior se usa para crear un nuevo objeto de consulta. Este nuevo objeto devuelve resultados diferentes a los del objeto de consulta original.
myQuery1 = from item in myQuery1
orderby item descending
select item;
// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}