Linq chọn các đối tượng trong danh sách tồn tại IN (A, B, C)


168

Tôi có một danh sách orders.
Tôi muốn chọn ordersdựa trên một tập hợp các trạng thái đơn hàng.

Vì vậy, về cơ bản 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;

Cảm ơn tất cả đã trả lời rất nhanh. Esp cho giải pháp lambda. Tôi chưa làm gì với biểu thức lambda. Tôi giả sử tôi KHÔNG chứa bằng cách sử dụng (o =>! (Statuses.Contains (o.OrderHeaderOrderStatusCode)))
MartinS

Câu trả lời:


287

Mã trạng thái của bạn cũng là một bộ sưu tập, vì vậy hãy sử dụng Contains:

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

hoặc trong cú pháp truy vấn:

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

1
Tôi sẽ nói rằng sử dụng Hashset thay vì mảng cho allowStatus vì phương thức chứa của Hashset là nhanh nhất và sẽ có vấn đề về hiệu năng với mảng nếu nó chứa hơn 1000 mục. 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;

15

NB: đây là LINQ cho các đối tượng, tôi không chắc chắn 100% nếu nó hoạt động trong LINQ cho các thực thể và không có thời gian để kiểm tra nó ngay bây giờ. Trên thực tế, không quá khó để dịch nó thành x trong [A, B, C] nhưng bạn phải tự kiểm tra.

Vì vậy, thay vì Chứa như là một thay thế của ???? trong mã của bạn, bạn có thể sử dụng Bất kỳ LINQ-uish nào:

// 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;

Nó trái ngược với những gì bạn biết từ SQL, đây là lý do tại sao nó không quá rõ ràng.

Tất nhiên, nếu bạn thích cú pháp trôi chảy ở đây thì đó là:

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

Ở đây, chúng ta lại thấy một trong những điều ngạc nhiên của LINQ (như bài phát biểu của Joda, chọn phần cuối). Tuy nhiên, điều này khá hợp lý theo nghĩa này là nó kiểm tra xem ít nhất một trong số các mục (đó là bất kỳ ) trong danh sách (bộ, bộ sưu tập) có khớp với một giá trị không.


12

Hãy thử với Containschức năng;

Xác định xem một chuỗi có chứa một yếu tố được chỉ định.

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

-3

Chỉ cần cẩn thận, .Contains()sẽ phù hợp với bất kỳ chuỗi con bao gồm cả chuỗi mà bạn không mong đợi. Ví dụ. new[] { "A", "B", "AA" }.Contains("A")sẽ trả lại cho bạn cả A và AA mà bạn có thể không muốn. Tôi đã bị nó cắn.

.Any()hoặc .Exists()là sự lựa chọn an toàn hơn


new [] {"B", "AA"} .Contains ("A") sẽ trả về false, KHÔNG đúng.
Jay Shah
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.