Linq wählt Objekte in der Liste aus, in denen IN (A, B, C) vorhanden ist.

168

Ich habe eine Liste von orders.
Ich möchte ordersbasierend auf einer Reihe von Auftragsstatus auswählen .

Also im Wesentlichen 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
quelle
Vielen Dank an alle, die so schnell geantwortet haben. Besonders für die Lambda-Lösung. Ich habe noch nichts mit Lambda-Ausdrücken gemacht. Ich nehme an, ich würde ein NICHT enthält enthält mit (o =>! (Statuses.Contains (o.OrderHeaderOrderStatusCode)))
MartinS

Antworten:

287

Ihre Statuscodes sind ebenfalls eine Sammlung. Verwenden Sie daher Contains:

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

oder in Abfragesyntax:

var filteredOrders = from order in orders.Order
                     where allowedStatus.Contains(order.StatusCode)
                     select order;
Tim Schmelter
quelle
1
Ich würde sagen, dass HashSet anstelle von Array für allowStatus verwendet wird, da die Include-Methode von HashSet am schnellsten ist und es Leistungsprobleme mit dem Array gibt, wenn es mehr als 1000 Elemente enthält. var allowStatus = new HashSet <string> {"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;

quelle
15

NB: Dies ist LINQ für Objekte. Ich bin nicht 100% sicher, ob es in LINQ für Entitäten funktioniert, und habe momentan keine Zeit, dies zu überprüfen. Tatsächlich ist es nicht allzu schwierig, es in [A, B, C] in x zu übersetzen , aber Sie müssen es selbst überprüfen.

Also, statt enthält als Ersatz für die ???? In Ihrem Code können Sie Any verwenden, das mehr LINQ-uish ist:

// 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 ist das Gegenteil von dem, was Sie aus SQL kennen. Deshalb ist es nicht so offensichtlich.

Wenn Sie hier eine fließende Syntax bevorzugen, ist dies natürlich:

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

Hier sehen wir wieder eine der LINQ-Überraschungen (wie die Joda-Rede, bei der Select am Ende steht). In diesem Sinne ist es jedoch ziemlich logisch, zu prüfen, ob mindestens eines der Elemente (dh eines ) in einer Liste (Satz, Sammlung) mit einem einzelnen Wert übereinstimmt.

Alexander Christov
quelle
12

Versuchen Sie es mit ContainsFunktion;

Legt fest, ob eine Sequenz ein bestimmtes Element enthält.

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

Seien Sie vorsichtig, .Contains()passt zu allen Teilzeichenfolgen, einschließlich der Zeichenfolge, die Sie nicht erwarten. Zum Beispiel.new[] { "A", "B", "AA" }.Contains("A")Sie erhalten sowohl A als auch AA zurück, die Sie möglicherweise nicht möchten. Ich bin davon gebissen worden.

.Any()oder .Exists()ist sicherer Wahl

Balvinder Singh
quelle
new [] {"B", "AA"} .Contains ("A") gibt false zurück, NICHT true.
Jay Shah