GroupBy和Select扩展方法帮助

时间:2014-03-27 17:47:02

标签: c# linq extension-methods

我正在使用以下代码尝试GroupBy几个字段:

var cars = tmp.Select(a => new { a.Make, a.Model, a.Year });

cars = cars.Distinct()
           .OrderBy(a => a.Make)
           .ThenBy(a => a.Model);

var groupedCars = cars.GroupBy(a => new { a.Make, a.Model })
                      .Select(b => new { b.Make, b.Model, b.Year });

不幸的是,最后一行代码给了我错误,因为无法识别这三个字段。

  

' System.Linq.IGrouping(AnonymousType#1,AnonymousType#2)'不包含'制作'的定义并没有延伸方法'制作'接受类型为System.Linq.IGrouping(AnonymousType#1,AnonymousType#2)'的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

所有三个字段(Make,Model,Year)都是相同的错误。

任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:6)

按品牌和型号对汽车进行分组后,序列中的每个元素都是一个组。您可以使用Key属性获取该组的密钥,这样您就可以找到该组MakeModel,但Year毫无意义。每组都会有多辆车,他们都可以有不同的年份。当然,您可以在组中使用信息。例如:

var groupedCars = cars.GroupBy(a => new { a.Make, a.Model })
                      .Select(g => new { g.Key.Make, g.Key.Model,
                                         MinYear = g.Min(car => car.Year),
                                         MaxYear = g.Max(car => car.Year) });

但从根本上说,你需要考虑这样一个事实,即序列的每个元素都是一个群体,而不是一辆汽车。

答案 1 :(得分:0)

我不会与Skeet的逻辑争辩,因为我的答案是相似的。

但我的建议是删除Select投影,该投影执行总结年份的结果选择器。这可以通过使用执行相同过程的GroupBy重载来完成。

cars.GroupBy (car => new { car.Make, car.Model }, // Key selector for make and model as keys
              vehicle => vehicle,                 // Element selector, we want all items of the original car instance which has the year
              (key, vehicle) => new               // Result selector, we want to sum up the min/max year of vehicle.
                                {
                                    Make  = key.Make,
                                    Model = key.Model,
                                    MinYear = vehicle.Min (car => car.Year),
                                    MaxYear = vehicle.Max (car => car.Year)
                                }
              );

结果如下所示:

enter image description here

关于这些数据:

var cars = new List<Car>
{
    new Car() { Make="Dodge", Model="Charger", Year=2007},
    new Car() { Make="BMW",   Model="M6",      Year=2007},
    new Car() { Make="Dodge", Model="Charger", Year=2012},
    new Car() { Make="BMW",   Model="X1",      Year=2013},
    new Car() { Make="BMW",   Model="X1",      Year=2014},
};