问题
I am trying to GroupBy a few fields using the following code:
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 });
Unfortunately, the very last line of code is giving me errors as is does not recognize the three fields.
'System.Linq.IGrouping(AnonymousType#1,AnonymousType#2)' does not contain a definition for 'Make' and no extension method 'Make' accepting a first argument of type 'System.Linq.IGrouping(AnonymousType#1,AnonymousType#2)' could be found (are you missing a using directive or an assembly reference?)
It is the same error for all three fields (Make, Model, Year).
Any ideas how to fix this?
回答1:
Once you've grouped the cars by make and model, each element of the sequence is a group. You can get the key for the group with the Key
property, so you can find the group's Make
and Model
, but Year
makes no sense... there will be multiple cars in each group, and they could all have different years. You can use the information within the group, of course. For example:
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) });
But fundamentally you need to be thinking about the fact that each element of the sequence is a group, not a single car.
回答2:
I am not going to argue with Skeet's logic for my answer is similar.
But my suggestion is to remove the Select
projection which does the result selector that sums up the years. That can be done by using the GroupBy overload which does the same process.
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)
}
);
Result looks like this:

on this data:
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},
};
来源:https://stackoverflow.com/questions/22695334/groupby-and-select-extension-method-assistance