LINQ - GroupBy类型

时间:2015-10-15 13:29:33

标签: c# linq

我继承了一些C#代码。我不完全理解类型在LINQ的上下文中是如何工作的。我有一些看起来像这样的代码:

foreach (var item in Model.Items.GroupBy(i => i.ID))
{ DoStuff(item); }

我尝试使用更复杂的分组来更新此代码。我尝试按IDDepartmentID进行分组。为了做到这一点,我有:

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>'

从这个错误中,我可以说我在完成两个分组时基本上构建了一个新类型。但是,我无法弄清楚如何按IDDepartmentID对项目进行分组,然后返回System.Linq.IGrouping<MyProject.Item>。我该怎么做?

3 个答案:

答案 0 :(得分:0)

根据我的经验,匿名类型无法使用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);
}

答案 1 :(得分:0)

组中的每个分组都是项目列表。您的groupTransform调用无效,因为您尝试订购的对象不是Model.Items对象,而是具有键的Model.Items对象列表。键是您使用ID和DepartmentID属性创建的匿名对象。

通常使用分组,您将拥有两个嵌套循环,而不仅仅是一个。外循环遍历每个分组。内循环遍历分组中的每个项目。你可以这样做:

.OrderBy(i => i.Name)

我添加了OrderBy和ThenBy调用,以帮助显示您如何使用分组键和分组中的项目。

答案 2 :(得分:0)

您的分组是正确的,但是您的订购导致问题。

执行分组后,您有多个ArrayList<Employee> employees = new ArrayList<Employee>(); empolyees.add(employee); 列表,因此,ItemName对这些群组进行排序只会在您按字段对字段进行分组时才有意义:< / p>

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 });