[英]LINQ - GroupBy Type
我繼承了一些C#代碼。 我不完全了解在LINQ上下文中類型如何工作。 我有一些看起來像這樣的代碼:
foreach (var item in Model.Items.GroupBy(i => i.ID))
{ DoStuff(item); }
我正在嘗試使用更復雜的分組來更新此代碼。 我正在嘗試按ID
和DepartmentID
進行分組。 為了做到這一點,我有:
var items = Model.Items.GroupBy(x => new { i.ID, i.DepartmentID }).OrderBy(i => i.Name).ThenByDescending(i => i.OrderDate);
foreach (var item in items)
{ DoStuff(item); }
編譯代碼時,出現編譯時錯誤:
Argument 1: cannot convert from 'System.Linq.IGrouping<<anonymous type:string ID, int DepartmentID>, MyProject.Item>' to 'System.Linq.IGrouping<MyProject.Item>'
從這個錯誤中可以看出,當我進行兩個分組時,我基本上已經建立了一個新類型。 但是,我無法弄清楚如何按項目的ID
和DepartmentID
項目進行分組,然后僅返回System.Linq.IGrouping<MyProject.Item>
。 我怎么做?
以我的經驗,匿名類型使您無法使用GroupBy
。 我要么創建一個新類,要么就不用花那么多精力,使用Tuple
:
new Tuple.Create(i.ID, i.DepartmentID)
那不是您現在使用的匿名類型:
new { i.ID, i.DepartmentID })
然后,在隨后的鏈接LINQ方法中的i
將成為一個分組,而不是Items
對象:
.OrderBy(i => i.Name) // this will not work
在這種情況下, i
將為IGrouping<Tuple<int, int>, Model.Items>
; 也就是說,它將是一個鍵值對。 在遍歷IGrouping
對象時,必須進行排序。
var groupings = Model.Items.GroupBy(x => new Tuple<int, int>(i.ID, i.DepartmentID));
foreach (var group in groupings)
{
var groupKey = group.Key;
group = group.OrderBy(i => i.Name).ThenByDescending(i => i.OrderDate);
foreach (var groupedItem in group)
DoStuff(groupKey, groupedItem);
}
該組中的每個分組都是一個項目列表。 您的.OrderBy(i => i.Name)
調用不起作用,因為您要訂購的對象不是Model.Items對象,而是帶有鍵的Model.Items對象列表。 密鑰是您使用ID和DepartmentID屬性創建的匿名對象。
通常,在分組時,您將有兩個嵌套循環,而不僅僅是一個。 外循環遍歷每個分組。 內部循環遍歷分組中的每個項目。 你可以這樣做:
foreach(var grouping in Model.Items
.GroupBy(x => new { i.ID, i.DepartmentID })
.OrderBy(b => b.Key.DepartmentID)
.ThenBy(t => t.Key.ID))
{
Console.WriteLine("{0}, {1}", grouping.Key.DepartmentID, grouping.Key.ID);
foreach(var item in grouping.OrderBy(n => n.Name).ThenByDescending(i => i.OrderDate))
{
Console.WriteLine("\t{0}", item.Name)
}
}
我添加了OrderBy和ThenBy調用,以幫助顯示如何使用分組鍵和分組中的項目。
您的分組正確,但是您的訂購導致了問題。
進行分組后,您將擁有許多Item
列表,因此,如果您也按thos字段對項目進行分組,則按Name
和OrderDate
排序組才有意義:
var items = Model.Items.GroupBy(x => new {
i.ID,
i.DepartmentID,
i.Name,
i.OrderDate })
.OrderBy(i => i.Name)
.ThenByDescending(i => i.OrderDate);
聽起來可能是在改變功能,而不是在追求什么。 如果希望按Name
和OrderDate
對每個分組列表進行排序,則可以在分組之前對Item
進行排序,盡管我會謹慎地保留順序
var itemGroups = Model.Items.OrderBy(i => i.Name)
.ThenByDescending(i => i.OrderDate)
.GroupBy(x => new {
i.ID,
i.DepartmentID,
i.Name,
i.OrderDate });
或者,最好在讀取每個列表時對其進行排序。
foreach(var itemGroup in itemGroups)
{
var orderedgroup = itemGroup.OrderBy(i => i.Name)
.ThenByDescending(i => i.OrderDate)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.