uso tutorial operadores metodo introduccion español consultas comandos clausula c# linq

tutorial - operadores en linq c#



Múltiples cláusulas WHERE con métodos de extensión LINQ (7)

Dos caminos:

results = results.Where(o => (o.OrderStatus == OrderStatus.Open) && (o.CustomerID == customerID));

o:

results = results.Where(o => (o.OrderStatus == OrderStatus.Open)) .Where(o => (o.CustomerID == customerID));

Por lo general prefiero el último. Pero vale la pena perfilar el servidor SQL para verificar la ejecución de la consulta y ver cuál funciona mejor para sus datos (si hay alguna diferencia).

Una nota sobre cómo encadenar los métodos .Where() : puede encadenar todos los métodos LINQ que desee. Métodos como .Where() no se ejecutan en realidad contra la base de datos (todavía). Difieren la ejecución hasta que se calculan los resultados reales (como con .Count() o a .ToList() ). Entonces, cuando encadenas varios métodos (más llamadas a .Where() , tal vez un .OrderBy() o algo por el estilo, etc.) construyen lo que se llama un árbol de expresiones . Este árbol completo es lo que se ejecuta contra el origen de datos cuando llega el momento de evaluarlo.

Tengo una consulta LINQ que se parece a la siguiente:

DateTime today = DateTime.UtcNow; var results = from order in context.Orders where ((order.OrderDate <= today) && (today <= order.OrderDate)) select order;

Estoy tratando de aprender / entender LINQ. En algunos casos, necesito agregar dos cláusulas WHERE adicionales. En un esfuerzo por hacer esto, estoy usando:

if (useAdditionalClauses) { results = results.Where(o => o.OrderStatus == OrderStatus.Open) // Now I''m stuck. }

Como puede ver, sé cómo agregar una cláusula WHERE adicional. ¿Pero cómo agrego múltiples? Por ejemplo, me gustaría agregar

WHERE o.OrderStatus == OrderStatus.Open AND o.CustomerID == customerID

a mi consulta anterior. ¿Cómo hago esto usando métodos de extensión?

¡Gracias!


Puedes continuar encadenándolos como lo has hecho.

results = results.Where (o => o.OrderStatus == OrderStatus.Open); results = results.Where (o => o.InvoicePaid);

Esto representa un AND.


Seguramente:

if (useAdditionalClauses) { results = results.Where(o => o.OrderStatus == OrderStatus.Open && o.CustomerID == customerID) }

O simplemente otra llamada .Where() como esta (aunque no sé por qué querrías, a menos que esté dividida por otra variable de control booleana):

if (useAdditionalClauses) { results = results.Where(o => o.OrderStatus == OrderStatus.Open). Where(o => o.CustomerID == customerID); }

O bien, otra reasignación a results : `results = results.Where ( blah ).


Si trabajas con datos en memoria (lee "colecciones de POCO") también puedes juntar tus expresiones usando PredicateBuilder así:

// initial "false" condition just to start "OR" clause with var predicate = PredicateBuilder.False<YourDataClass>(); if (condition1) { predicate = predicate.Or(d => d.SomeStringProperty == "Tom"); } if (condition2) { predicate = predicate.Or(d => d.SomeStringProperty == "Alex"); } if (condition3) { predicate = predicate.And(d => d.SomeIntProperty >= 4); } return originalCollection.Where<YourDataClass>(predicate.Compile());

La fuente completa de PredicateBuilder mencionado está abajo (pero también puede consultar la PredicateBuilder con algunos ejemplos más):

using System; using System.Linq; using System.Linq.Expressions; using System.Collections.Generic; public static class PredicateBuilder { public static Expression<Func<T, bool>> True<T> () { return f => true; } public static Expression<Func<T, bool>> False<T> () { return f => false; } public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ()); return Expression.Lambda<Func<T, bool>> (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters); } public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ()); return Expression.Lambda<Func<T, bool>> (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters); } }

Nota : He probado este enfoque con el proyecto Portable Class Library y tengo que usar .Compile() para que funcione:

Donde (predicado .Compile () );


Solo use el operador && como lo haría con cualquier otra declaración que necesite para hacer lógica booleana.

if (useAdditionalClauses) { results = results.Where( o => o.OrderStatus == OrderStatus.Open && o.CustomerID == customerID) }


puede usar && y escribir todas las condiciones en la misma cláusula where, o puede .Where (). Where (). Where () ... y así sucesivamente.


results = context.Orders.Where(o => o.OrderDate <= today && today <= o.OrderDate)

La selección no se realiza porque ya está trabajando con una orden.