Linq selecciona objetos en la lista donde existe IN (A, B, C)

169

Tengo una lista de orders .
Quiero seleccionar en ordersfunción de un conjunto de estados de pedido.

Entonces esencialmente select orders where order.StatusCode in ("A", "B", "C")

// Filter the orders based on the order status
var filteredOrders = from order in orders.Order
                     where order.StatusCode.????????("A", "B", "C")
                     select order;
MartinS
fuente
Gracias a todos los que respondieron tan rápido. Esp para la solución lambda. Todavía no he hecho nada con expresiones lambda. Supongo que haría un NO contiene usando (o =>! (Statuses.Contains (o.OrderHeaderOrderStatusCode)))
MartinS

Respuestas:

288

Sus códigos de estado también son una colección, así que use Contains:

var allowedStatus = new[]{ "A", "B", "C" };
var filteredOrders = orders.Order.Where(o => allowedStatus.Contains(o.StatusCode));

o en sintaxis de consulta:

var filteredOrders = from order in orders.Order
                     where allowedStatus.Contains(order.StatusCode)
                     select order;
Tim Schmelter
fuente
1
Yo diría que use HashSet en lugar de array para allowStatus porque el método contiene HashSet es más rápido y habrá problemas de rendimiento con la matriz si contiene más de 1000 elementos. var allowedStatus = new HashSet <cadena> {"A", "B", "C"};
Jay Shah
15
var statuses = new[] { "A", "B", "C" };

var filteredOrders = from order in orders.Order
                             where statuses.Contains(order.StatusCode)
                             select order;

fuente
15

NB: esto es LINQ para objetos, no estoy 100% seguro si funciona en LINQ para entidades, y no tengo tiempo para verificarlo ahora. De hecho, no es demasiado difícil traducirlo a x en [A, B, C], pero debe verificarlo usted mismo.

Entonces, en lugar de Contiene como un reemplazo del ???? en tu código puedes usar Any, que es más LINQ-uish:

// Filter the orders based on the order status
var filteredOrders = from order in orders.Order
                     where new[] { "A", "B", "C" }.Any(s => s == order.StatusCode)
                     select order;

Es lo opuesto a lo que sabes de SQL, por eso no es tan obvio.

Por supuesto, si prefiere una sintaxis fluida aquí es:

var filteredOrders = orders.Order.Where(order => new[] {"A", "B", "C"}.Any(s => s == order.StatusCode));

Aquí nuevamente vemos una de las sorpresas de LINQ (como Joda-speech que pone select al final). Sin embargo, es bastante lógico en este sentido que verifique si al menos uno de los elementos (que es alguno ) en una lista (conjunto, colección) coincide con un valor único.

Alexander Christov
fuente
12

Probar con la Containsfunción;

Determina si una secuencia contiene un elemento especificado.

var allowedStatus = new[]{ "A", "B", "C" };
var filteredOrders = orders.Order.Where(o => allowedStatus.Contains(o.StatusCode));
Soner Gönül
fuente
-3

Solo tenga cuidado, .Contains()coincidirá con cualquier subcadena, incluida la cadena que no espera. Por ej.new[] { "A", "B", "AA" }.Contains("A")le devolverá tanto A como AA que quizás no desee. He sido mordido por eso.

.Any()o .Exists()es una opción más segura

Balvinder Singh
fuente
nuevo [] {"B", "AA"} .Contains ("A") devolverá falso, NO verdadero.
Jay Shah