Let's say I have this list of objects:
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 = "" }
}
}
};
I need the query that would check and return only shipment tracking(s) that has trackingCode == "DSP" but not shipment tracking with "CCI" or "POD" trackingCode, so in this example shipment tracking with tracking number 32021001002 would be the one.
I have tried this but doesn't seem to work:
foreach (var shipment in shipments)
{
var foo = shipment.trackings.FirstOrDefault((t => t.trackingCode == "DSP" && t.trackingCode != "CCI"));
if (shipment.trackings.Contains(foo))
{
}
}
Any help or pointer is appreciated. Thanks!
CodePudding user response:
You want shipments where for the list of trackings: there IS any tracking code "DSP" and there IS NOT any tracking code "CCI"
shipments.Where(s =>
s.Trackings.Any(t => t.TrackingCode == "DSP") &&
!s.Trackings.Any(t => t.TrackingCode == "CCI")
);
You could also write this as:
shipments.Where(s =>
s.Trackings.Any(t => t.TrackingCode == "DSP") &&
s.Trackings.All(t => t.TrackingCode != "CCI")
);
i.e. shipments where there is any tracking code that is DSP, and all the tracking codes are not CCI"
Use whichever makes more sense to you
CodePudding user response:
has trackingCode == "DSP" but not shipment tracking with "CCI" or "POD"
I would fill two collections to simplify it and to make it easy to be changed:
var validCodes = new List<string>{"DSP"};
var invalidCodes = new List<string>{"CCI", "POD"};
If you want to ignore the case, so treat dsp
and DSP
same you need StringComparer.OrdinalIgnoreCase
, otherwise StringComparer.Ordinal
.
The query is pretty simple:
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();
Instead of two Where
you can also use one with &&
. I prefer two because it's easier to read.