Linq เลือกวัตถุในรายการที่มีอยู่ใน (A, B, C)


170

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 สำหรับแลมบ์ดาโซลูชั่น ฉันยังไม่ได้ทำสิ่งใดด้วยการแสดงออกแลมบ์ดา ฉันถือว่าฉันไม่มีการใช้ (o =>! (statuses.Contains (o.OrderHeaderOrderStatusCode)))
MartinS

คำตอบ:


289

รหัสสถานะของคุณเป็นของสะสมเช่น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 แทน array สำหรับ allowStatus เนื่องจาก HashSet มีวิธีที่เร็วที่สุดและจะมีปัญหาเรื่องประสิทธิภาพการทำงานของอาเรย์ถ้ามันมีมากกว่า 1,000 รายการ var allowStatus = ใหม่ 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

หมายเหตุ:นี่คือ LINQ สำหรับวัตถุฉันไม่แน่ใจ 100% ว่ามันใช้งานได้ใน LINQ กับหน่วยงานหรือไม่และไม่มีเวลาที่จะตรวจสอบในตอนนี้ ในความเป็นจริงมันไม่ยากเกินไปที่จะแปลเป็นx ใน [A, B, C]แต่คุณต้องตรวจสอบด้วยตัวเอง

ดังนั้นแทนที่จะมีเป็นแทนของ???? ในรหัสของคุณคุณสามารถใช้ใด ๆซึ่งเป็น 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-speech ซึ่งทำให้เลือกได้ในตอนท้าย) อย่างไรก็ตามมันค่อนข้างสมเหตุสมผลในแง่นี้ว่ามันตรวจสอบว่าอย่างน้อยหนึ่งรายการ (นั่นคือมี ) ในรายการ (ชุดคอลเลกชัน) ตรงกับค่าเดียว


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()เป็นทางเลือกที่ปลอดภัยกว่า


ใหม่ [] {"B", "AA"}. เนื้อหา ("A") จะส่งคืนค่าเท็จไม่เป็นความจริง
Jay Shah
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.