有沒有辦法使用 LINQ 根據屬性值搜索嵌套在另一個串列中的串列中的專案?
鑒于以下模型,對于給定的訂單(變數customerOrder),我想回傳最早的訂單日期(Date),其中日期為“星期日”。
楷模:
public class Order
{
public int Id { get; set; }
public List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
public string Description { get; set; }
public List<OrderDate> OrderDates { get; set; }
}
public class OrderDate
{
public DateTime Date { get; set; }
public string Day { get; set; }
}
代碼:
var dates = new List<DateTime>();
foreach(var a in customerOrder.OrderLines)
{
var orderDate = a.OrderDates.Where(x => x.DateTypeId.Equals("Sunday")).FirstOrDefault();
dates.Add(orderDate.ActualDate);
}
dates.OrderBy(d => d.Date);
return dates.FirstOrDefault();
uj5u.com熱心網友回復:
編輯 更優雅的查詢
您可以使用 Linq 來實作您的結果。
這是一個可以密切模仿您的代碼的查詢。
customerOrder.OrderLines
.Select(ol => ol.OrderDates
.Where(x => x.Day.Equals("Sunday"))
.FirstOrDefault())
.Where(d => d != null)
.OrderBy(d => d.Date)
.FirstOrDefault();
可以更優雅地重寫為:
customerOrder.OrderLines
.SelectMany(ol => ol.OrderDates)
.OrderBy(d => d.Date)
.FirstOrDefault(d => d.Day == "Sunday");
這是一個帶有一些測驗資料和轉儲的 Linqpad 查詢供您嘗試。只需在 Linqpad 中復制和粘貼即可。
void Main()
{
var customerOrder = new Order
{
Id = 1,
OrderLines = Enumerable
.Range(0, 10)
.Select(i => new OrderLine
{
Description = $"Line Description {i}",
OrderDates = Enumerable.Range(0, 10)
.Select(j => new OrderDate
{
Date = DateTime.Now.AddDays(i j),
Day = DateTime.Now.AddDays(i j).DayOfWeek.ToString()
})
.ToList()
})
.ToList()
}
.Dump();
customerOrder.OrderLines
.SelectMany(ol => ol.OrderDates)
.OrderBy(d => d.Date)
.FirstOrDefault(d => d.Day == "Sunday")
.Dump();
}
// You can define other methods, fields, classes and namespaces here
public class Order
{
public int Id { get; set; }
public List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
public string Description { get; set; }
public List<OrderDate> OrderDates { get; set; }
}
public class OrderDate
{
public DateTime Date { get; set; }
public string Day { get; set; }
}
附帶說明一下,OrderDate該類不是必需的。該DateTime型別具有DayOfWeek可用于測驗的屬性是日期是星期日。
DayOfWeek是一個列舉,因此您可以簡單地測驗MyDate.DayOfWeek == DayOfWeek.Sunday而不是依賴 astring來實作該目的。
uj5u.com熱心網友回復:
首先,您的代碼將無法按預期作業。
dates.OrderBy(d => d.Date);不起作用:OrderBy回傳一個 IEnumerable,它不會改變原始集合。您應該使用List.Sort` 或這樣做:
dates = dates.OrderBy(d => d.Date).ToList()
其次,您使用FirstOrDefault:它有一個多載,可以接受謂詞進行搜索;所以Where不需要呼叫。此外,null如果沒有找到,FirstOrDefault 將回傳。如果這是一種可能的情況,您應該考慮檢查是否orderDate為空:
var dates = new List<DateTime>();
foreach(var a in customerOrder.OrderLines)
{
var orderDate = a.OrderDates.FirstOrDefault(x => x.DateTypeId.Equals("Sunday"));
if (orderDate is {})
{
dates.Add(orderDate.ActualDate);
}
}
dates = dates.OrderBy(d => d.Date).ToList();
return dates.FirstOrDefault();
那應該可以正常作業。但是很難猜測代碼示例的哪些方面的行為是有意的,哪些方面不是。您詢問搜索,但沒有提及 OrderBy 部分。你能澄清一下這部分嗎?
回答這個問題,如果better你的意思是更緊湊的方式,你可以用這樣的方法:
var result = customerOrder.OrderLines
.SelectMany(a => a.OrderDates)
.OrderBy(d => d.Date)
.FirstOrDefault(x => x.DateTypeId.Equals("Sunday"));
return result;
你better way現在不應該被打擾;首先,您應該至少從working way. 我建議你學習如何使用 Linq 和不使用 Linq 來做這些事情。
uj5u.com熱心網友回復:
Better 有點主觀,但您可以使用Enumerable.SelectMany擴展方法將OrderDate實體展平為一個序列。
然后您可以使用Enumerable.Where擴展方法來過濾"Sunday".
然后您可以使用Enumerable.Min擴展方法來獲取最小日期。
所有這些都可以鏈接到一個陳述句中。
DateTime earliestSunday = customeOrder
.OrderLines
.SelectMany(ol => ol.OrderDates)
.Where(od => od.Day == "Sunday")
.Min(od => od.Date);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/360030.html
下一篇:多個子句阻塞整個過濾器
