Tengo una consulta LINQ que se parece a lo 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 varios? 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 seguir encadenándolos como lo has hecho.
Esto representa un AND.
fuente
Si trabaja con datos en memoria (lea "colecciones de POCO"), también puede apilar sus expresiones juntas 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 lo mencionado se
PredicateBuilder
encuentra a continuación (pero también puede consultar la página original 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 de biblioteca de clases portátil y tengo que usarlo
.Compile()
para que funcione:fuente
Seguramente:
if (useAdditionalClauses) { results = results.Where(o => o.OrderStatus == OrderStatus.Open && o.CustomerID == customerID) }
O simplemente otra
.Where()
llamada como esta (aunque no sé por qué querría hacerlo, 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 otra reasignación a
results
: `results = results.Where ( blah ).fuente
puede usar && y escribir todas las condiciones en la misma cláusula where, o puede .Where (). Where (). Where () ... y así sucesivamente.
fuente
La selección no es necesaria porque ya está trabajando con un pedido.
fuente
Simplemente 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) }
fuente