簡體   English   中英

LINQ 檢查對象列表包含一個值而不是其他一些值

[英]LINQ check list of objects contain a value AND not some other values

假設我有這個對象列表:

var shipments = new List<ShipmentTracking>() {
    new ShipmentTracking() {
        trackingNumber = "32021001000", trackings = new List<Tracking>() {
            new Tracking() { trackingCode = "EBC", trackingPoint = "Entered", trackingDateTime = DateTime.Now, trackingMemo = "" }
        }
    },
    new ShipmentTracking() {
        trackingNumber = "32021001001", trackings = new List<Tracking>() {
            new Tracking() { trackingCode = "EBC", trackingPoint = "Entered", trackingDateTime = DateTime.Now.AddDays(1), trackingMemo = "" },
            new Tracking() { trackingCode = "AWB", trackingPoint = "Registered", trackingDateTime = DateTime.Now.AddDays(1), trackingMemo = "" }
        }
    },
    new ShipmentTracking() {
        trackingNumber = "32021001002", trackings = new List<Tracking>() {
            new Tracking() { trackingCode = "EBC", trackingPoint = "Entered", trackingDateTime = DateTime.Now.AddDays(2), trackingMemo = "" },
            new Tracking() { trackingCode = "AWB", trackingPoint = "Registered", trackingDateTime = DateTime.Now.AddDays(2), trackingMemo = "" },
            new Tracking() { trackingCode = "DSP", trackingPoint = "Shipped", trackingDateTime = DateTime.Now.AddDays(2), trackingMemo = "" }
        }
    },
    new ShipmentTracking() {
        trackingNumber = "32021001003", trackings = new List<Tracking>() {
            new Tracking() { trackingCode = "EBC", trackingPoint = "Entered", trackingDateTime = DateTime.Now.AddDays(3), trackingMemo = "" },
            new Tracking() { trackingCode = "AWB", trackingPoint = "Registered", trackingDateTime = DateTime.Now.AddDays(3), trackingMemo = "" },
            new Tracking() { trackingCode = "DSP", trackingPoint = "Shipped", trackingDateTime = DateTime.Now.AddDays(3), trackingMemo = "" },
            new Tracking() { trackingCode = "CCI", trackingPoint = "Cleared", trackingDateTime = DateTime.Now.AddDays(3), trackingMemo = "" }
        }
    },
    new ShipmentTracking() {
        trackingNumber = "32021001003", trackings = new List<Tracking>() {
            new Tracking() { trackingCode = "EBC", trackingPoint = "Entered", trackingDateTime = DateTime.Now.AddDays(4), trackingMemo = "" },
            new Tracking() { trackingCode = "AWB", trackingPoint = "Registered", trackingDateTime = DateTime.Now.AddDays(4), trackingMemo = "" },
            new Tracking() { trackingCode = "DSP", trackingPoint = "Shipped", trackingDateTime = DateTime.Now.AddDays(4), trackingMemo = "" },
            new Tracking() { trackingCode = "CCI", trackingPoint = "Cleared", trackingDateTime = DateTime.Now.AddDays(4), trackingMemo = "" },
            new Tracking() { trackingCode = "POD", trackingPoint = "Delivered", trackingDateTime = DateTime.Now.AddDays(4), trackingMemo = "" }
        }
    }
};

我需要的查詢將檢查並僅返回具有 trackingCode == "DSP" 但不使用 "CCI" 或 "POD" trackingCode 的貨件跟蹤的貨件跟蹤,因此在此示例中,跟蹤號為 32021001002 的貨件跟蹤將是一。

我已經嘗試過了,但似乎不起作用:

foreach (var shipment in shipments)
{
    var foo = shipment.trackings.FirstOrDefault((t => t.trackingCode == "DSP" && t.trackingCode != "CCI"));

    if (shipment.trackings.Contains(foo))
    {
        
    }
}

任何幫助或指針表示贊賞。 謝謝!

您想要在哪里提供跟蹤列表:有任何跟蹤代碼“DSP”並且沒有任何跟蹤代碼“CCI”

shipments.Where(s => 
  s.Trackings.Any(t => t.TrackingCode == "DSP") && 
  !s.Trackings.Any(t => t.TrackingCode == "CCI")
);

你也可以這樣寫:

shipments.Where(s => 
  s.Trackings.Any(t => t.TrackingCode == "DSP") && 
  s.Trackings.All(t => t.TrackingCode != "CCI")
);

有任何跟蹤代碼是 DSP 並且所有跟蹤代碼都不是 CCI 的貨物”

使用對您更有意義的

有 trackingCode == "DSP" 但沒有帶有 "CCI" 或 "POD" 的貨物跟蹤

我將填充兩個 collections 以簡化它並使其易於更改:

var validCodes = new List<string>{"DSP"};
var invalidCodes = new List<string>{"CCI", "POD"};

如果您想忽略這種情況,那么將dspDSP視為相同,您需要StringComparer.OrdinalIgnoreCase ,否則StringComparer.Ordinal

查詢非常簡單:

List<ShipmentTracking> trackingList = shipments
    .Where(st => st.trackings.Any(t => validCodes.Contains(t.trackingCode, StringComparer.OrdinalIgnoreCase)))
    .Where(st => !st.trackings.Any(t => invalidCodes.Contains(t.trackingCode, StringComparer.OrdinalIgnoreCase)))
    .ToList();

而不是兩個Where你也可以使用一個&& 我更喜歡兩個,因為它更容易閱讀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM