Linq вибирає об’єкти у списку, де існує IN (A, B, C)


169

У мене є список orders.
Я хочу вибрати ordersна основі набору статусів замовлень.

Так по суті 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;

Дякую всім, хто відповів так швидко. Esp для розчину лямбда. Я ще нічого не робив з лямбдаськими виразами. Я припускаю, що я б робив NOT, що використовує (o =>! (Statuses.Contains (o.OrderHeaderOrderStatusCode)))
MartinS

Відповіді:


288

Ваші коди статусу також є колекцією, тому використовуйте Contains:

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

або в синтаксисі запиту:

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

1
Я б сказав, що використовувати HashSet замість масиву для разрешеногоStatus, оскільки метод методу HashSet є найшвидшим, і з масивом виникнуть проблеми з продуктивністю, якщо він містить більше 1000 елементів. var allowedStatus = new HashSet <string> {"A", "B", "C"};
Джей Шах

15
var statuses = new[] { "A", "B", "C" };

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

15

Примітка: це LINQ для об'єктів, я не впевнений на 100%, чи працює він у LINQ для сутностей, і не маю часу перевірити його зараз. Насправді перекласти це на x в [A, B, C] не так вже й складно , але ви повинні перевірити самі.

Отже, замість Contains в якості заміни ???? у своєму коді ви можете використовувати будь- який, який є більш 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;

Це навпаки тому, що ви знаєте з SQL, тому це не так очевидно.

Звичайно, якщо ви віддаєте перевагу вільному синтаксису тут:

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

Тут ми знову бачимо одне з сюрпризів LINQ (як-от Joda-промова, яка ставить select у кінці). Однак у цьому сенсі цілком логічно, що він перевіряє, чи принаймні один із елементів (тобто будь-який ) у списку (набір, колекція) відповідає одному значенню.


12

Спробуйте з Containsфункцією;

Визначає, чи містить послідовність вказаний елемент.

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

-3

Будьте обережні, .Contains()відповідатиме будь-яка підрядка, включаючи рядок, якої ви не очікуєте. Наприклад, наприклад. new[] { "A", "B", "AA" }.Contains("A")поверне вам і A, і AA, чого ви, можливо, не захочете. Мене це покусало.

.Any()або .Exists()це безпечніший вибір


new [] {"B", "AA"} .Contains ("A") поверне помилкові, НЕ істинні.
Джей Шах
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.