C# LINQ-按类型分组
我继承了一些C代码。我不完全理解类型在LINQ上下文中是如何工作的。我有一些代码如下所示:C# LINQ-按类型分组,c#,linq,C#,Linq,我继承了一些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 }).
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>'
参数1:无法从'System.Linq.IGrouping'转换为'System.Linq.IGrouping'
从这个错误中,我可以看出,当我进行两个分组时,我基本上构建了一个新类型。但是,我不知道如何按项目的
ID
和DepartmentID
对项目进行分组,然后返回一个System.Linq.IGrouping
。我该怎么做呢?以我的经验,匿名类型在GroupBy
中毫无用处。我要么创建一个新类,当然不值得那么多努力,要么使用元组:
new Tuple.Create(i.ID, i.DepartmentID)
而不是您现在使用的匿名类型:
new { i.ID, i.DepartmentID })
随后链式LINQ方法中的i
将是一个分组,而不是项
对象:
.OrderBy(i => i.Name) // this will not work
在这种情况下,i
将是一个i分组
;也就是说,它将是一个键值对。您必须在循环通过i分组
对象时进行排序
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);
}
var-groupings=Model.Items.GroupBy(x=>newtuple(i.ID,i.DepartmentID));
foreach(分组中的var组)
{
var groupKey=group.Key;
group=group.OrderBy(i=>i.Name),然后按降序(i=>i.OrderDate);
foreach(组中的var groupedItem)
DoStuff(groupKey,groupedItem);
}
以我的经验,匿名类型在GroupBy
中毫无用处。我要么创建一个新类,当然不值得那么多努力,要么使用元组:
new Tuple.Create(i.ID, i.DepartmentID)
而不是您现在使用的匿名类型:
new { i.ID, i.DepartmentID })
随后链式LINQ方法中的i
将是一个分组,而不是项
对象:
.OrderBy(i => i.Name) // this will not work
在这种情况下,i
将是一个i分组
;也就是说,它将是一个键值对。您必须在循环通过i分组
对象时进行排序
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);
}
var-groupings=Model.Items.GroupBy(x=>newtuple(i.ID,i.DepartmentID));
foreach(分组中的var组)
{
var groupKey=group.Key;
group=group.OrderBy(i=>i.Name),然后按降序(i=>i.OrderDate);
foreach(组中的var groupedItem)
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和by调用,以帮助显示如何使用分组键和分组中的项目。组中的每个分组都是项目列表。您的.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和by调用,以帮助显示如何使用分组键和分组中的项目。您的分组是正确的,但您的排序导致了问题
执行分组后,您有许多项目的列表
,因此,仅当您也按这些字段对项目进行分组时,按名称
和订单日期
对组进行排序才有意义:
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
排序,那么您可以在分组之前对项目进行排序,尽管我会谨慎地保留排序
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)
}
您的分组是正确的,但您的顺序导致了问题
执行分组后,您有许多项目的列表
,因此,仅当您也按这些字段对项目进行分组时,按名称
和订单日期
对组进行排序才有意义:
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
排序,那么您可以在分组之前对项目进行排序,尽管我会谨慎地保留排序
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)
}
我相信如果你想从新元组(I.ID,I.DepartmentID)到元组,你可以把它缩短。Create(I.ID,I.DepartmentID)我相信如果你想从新元组(I.ID,I.DepartmentID)到元组,你可以把它缩短。Create(I.ID,I.DepartmentID)OP希望通过名称
和订单日期
订购。OP希望通过名称
和订单日期
订购。