Home > Software engineering >  Linq GroupBy not projecting all properties
Linq GroupBy not projecting all properties

Time:03-07

Good Morning,

I have a List<> of location reviews and the GroupBy I have written accurately groups them. However it will only allow two items to be projected and I can't find (googling) how to project the other properties.

In looking at the GroupBy definition I'm not even sure it's the correct extension method to use for my desired outcome but I can't find any alternatives.

My ungrouped collection is a List I'm just using json notation to convey the structure.

userLocationReviews {
   userReview[0] {
    BusinessId="1234",
    BusinessName="Wonka Chocolate",
    LocationId = "443456",
    CityName="MyTown",
    RatingVale=5
   }
   userReview[1] {...}
   userReview[2] {...}
   ...
   userReview[100] {...}
}

I wrote this GroupBy and it is correct.

var groupedReviewedLocations = userLocationReviews.UserReviews.GroupBy(
    p => p.LocationId,
    p => p.RatingValue,
    (locId, rating) => new {LocationId = locId, Ratings = rating.ToList() });

Again this is a List just using json to show structure instead of a screen snippet.

groupedReviewLocations {
   Non-Public Members {...},
   ResultsView {
    [0]{
      LocationId: "1234",
      Ratings: {
        0:3,
        1:5,
        2:1,
        3:5
      }
    },
    [1]{...},
    .....
    [15]{...}
   }
}

However as mentioned above how do I get the other properties into the projection?

groupedReviewLocations {
   Non-Public Members {...},
   ResultsView {
    [0]{
      LocationId: "1234",
      Ratings: {},
      BusinessName: "Wonka Chocolate",
      CityName: "MyTown"
    },
    [1]{...},
    .....
    [15]{...}
   }
}

TIA

CodePudding user response:

Remove the

p => p.RatingValue,

line entirely

The group by is done by LocationId but by using this particular overload of GroupBy:

GroupBy(
  key-chooser,
  value-chooser,
  (Key, Values) list-processor
)

you're specifying which property you want in the output list in the second argument (value chooser).

If you instead use this overload:

GroupBy(
  key-chooser,
  (Key, Values) list-processor
)

The value is automatically determined to be the entire input object. You could also change the p => p.RatingValue, so it's just p => p, for the same effect (if that helps you understand what's going on)


It would make sense to change the (locId, rating) to (locId, reviewedLocations) as the second argument to that lambda will now be the list of location objects that share a key, rather than just a list of ratings. Also, because the second argument (you called it rating, I called it reviewedLocations) is a collection/multiple things it makes sense to give it a plural name

  • Related