我继承了一些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>
。我该怎么做?
答案 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);
列表,因此,Item
和Name
对这些群组进行排序只会在您按字段对字段进行分组时才有意义:< / 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 });