I am attempting to write a Linq query to return a parent object identified by matching to a property of one of its child objects. My class is a Sales Order which has a list of Deliveries which in turn has a list of LineItems. I would like to return a Delivery object when there is a match to the Item Number and Line Number properties in a Delivery's LineItems.
Classes:
public class SalesOrderDetail
{
[JsonProperty("SalesOrderNumber")]
public string SalesOrderNumber { get; set; }
[JsonProperty("PONumber")]
public string PONumber { get; set; }
[JsonProperty("Status")]
public string Status { get; set; }
[JsonProperty("Deliveries")]
public List<Delivery> Deliveries { get; set; }
}
public class Delivery
{
[JsonProperty("DeliveryDocumentNumber")]
public string DeliveryDocumentNumber { get; set; }
[JsonProperty("DeliveryStatus")]
public string DeliveryStatus { get; set; }
[JsonProperty("Parcels")]
public List<Parcel> Parcels { get; set; }
[JsonProperty("LineItems")]
public List<LineItem> LineItems { get; set; }
[JsonProperty("ShippedDate")]
public DateTime ShippedDate { get; set; }
}
public class LineItem
{
[JsonProperty("DeliveryDocumentLineNumber")]
public int DeliveryDocumentLineNumber { get; set; }
[JsonProperty("OrderLineNumber")]
public int OrderLineNumber { get; set; }
[JsonProperty("ItemNumber")]
public string ItemNumber { get; set; }
[JsonProperty("QuantityOrdered")]
public int QuantityOrdered { get; set; }
[JsonProperty("QuantityPicked")]
public int QuantityPicked { get; set; }
[JsonProperty("QuantityScanned")]
public int QuantityScanned { get; set; }
[JsonProperty("QuantityShipped")]
public int QuantityShipped { get; set; }
[JsonProperty("QuantityCanceled")]
public int QuantityCanceled { get; set; }
[JsonProperty("LineItemDetails")]
public List<LineItemDetail> LineItemDetails { get; set; }
}
Example JSON:
{
"SalesOrderNumber": "0017320457",
"PONumber": "PON0234250",
"Status": "Completely Shipped",
"Deliveries": [
{
"DeliveryDocumentNumber": "0088148528",
"DeliveryStatus": "Shipped",
"Parcels": [
{
"CartonNumber": "00093456780095683506",
"CarrierCode": "FEDG",
"TrackingType": "TRACKING",
"TrackingNumber": "946346636541",
"Weight": 12.22,
"WeightUOM": "LB"
}
],
"LineItems": [
{
"DeliveryDocumentLineNumber": 10,
"OrderLineNumber": 10,
"ItemNumber": "SYM-LS2208SR20007RUR",
"QuantityOrdered": 1,
"QuantityPicked": 0,
"QuantityScanned": 0,
"QuantityShipped": 1,
"QuantityCanceled": 0,
"LineItemDetails": [
{
"CartonNumber": "00093456780095683506",
"SerialNumber": "SZ3M7Z8",
"MACAddress": null,
"MACAddressUnformatted": null
}
]
},
],
"ShippedDate": "2021-03-05T03:32:43.903"
}
]
"Deliveries": [
{
"DeliveryDocumentNumber": "0088148351",
"DeliveryStatus": "Shipped",
"Parcels": [
{
"CartonNumber": "000934567800956835901",
"CarrierCode": "FEDG",
"TrackingType": "TRACKING",
"TrackingNumber": "946346636443",
"Weight": 10.24,
"WeightUOM": "LB"
}
],
"LineItems": [
{
"DeliveryDocumentLineNumber": 20,
"OrderLineNumber": 20,
"ItemNumber": "ZEB-ZD62142T01F00EZ",
"QuantityOrdered": 1,
"QuantityPicked": 0,
"QuantityScanned": 0,
"QuantityShipped": 1,
"QuantityCanceled": 0,
"LineItemDetails": [
{
"CartonNumber": "000934567800956835901",
"SerialNumber": "D1N204401680",
"MACAddress": null,
"MACAddressUnformatted": null
}
]
},
],
"ShippedDate": "2021-03-04T03:32:43.903"
}
]
}
The way I started thinking about this is to write the following code. Intellisense states it will return an object of type Delivery, however, a test of the code generates the exception "Sequence contain no elements".
int lineNumber = 10;
string itemNumber = "SYM-LS2208SR20007RUR";
var matchedDelivery = salesOrderDetail.Deliveries.Where(f => f.LineItems == f.LineItems.Where(l => (l.ItemNumber == itemNumber) && (l.OrderLineNumber == lineNumber))).First();