Grouping reviews by UserId The class I'm using is called Review and looks like this:

public class Review
{
    public virtual Guid Id { get; set; }

    public virtual int Rating { get; set; }

    public virtual Guid RestaurantId { get; set; }

    public virtual Guid UserId { get; set; }
}


I'm using a LINQ statement to first check a few things and afterwards group by a user's reviews. I'll explain what I mean with this:

var reviewsByUsers = 
    reviews
    .GroupBy(x =&gt; x.RestaurantId)
    .Where(x =&gt; x.Count() &gt;= 3)
    .SelectMany(x =&gt; x.ToList())
    .Distinct()
    .GroupBy(x =&gt; x.UserId)
    .Where(x =&gt; x.Count() &gt;= 2)
    .Select(x =&gt; x.ToList())
    .ToList();


And now step by step:

1. reviews is a list of all reviews given on a bunch of restaurants. This is not the database, it's a list I receive as a parameter of the method.

2. .GroupBy(x =&gt; x.RestaurantId) Group these reviews per each restaurant. This is for counting them later.

3. .Where(x =&gt; x.Count() &gt;= 3) Exclude any restaurants which don't have 3 or more reviews on them.

4. .SelectMany(x =&gt; x.ToList()) Flatten the list so we can group again.

5. .Distinct() To be sure that I'm not getting doubles.

6. .GroupBy(x =&gt; x.UserId) Group the reviews per user. This is for counting them later.

7. .Where(x =&gt; x.Count() &gt;= 2) Exclude any user which has less than 2 reviews.

8. .Select(x =&gt; x.ToList()) I don't need anything else per user, a list of reviews per user is enough.

All of this will result in a List&lt;List&lt;Review&gt;&gt; which is a list that contains a list of all reviews grouped by the UserId.

I'm certain there has to be a better way to perform these checks and create a list of lists grouped by user id. I'm just very new to C#, so I don't know how to increase this LINQ statement.
There is actaully another solution that utilizes the Except extension. This means you first select all reviews with at least two users but remove those where the restaurant does not have at least three reviews.

This requires to write a new IEqualityComparer that I find is an overkill for this but on the other hand the Except clearly tells what kind of results we don't want to have. Anyway, the alternative solution:

reviews
    .GroupBy(r =&gt; r.UserId)
    .Where(g =&gt; g.Count() &gt; 1)
    .Except(
        reviews
            .GroupBy(r =&gt; r.RestaurantId)
            .Where(g =&gt; g.Count() &lt; 3),
        new ReviewComparer()
    );


where

class ReviewComparer : IEqualityComparer&lt;IGrouping&lt;Guid, Review&gt;&gt;
{
    public bool Equals(IGrouping&lt;Guid, Review&gt; left, IGrouping&lt;Guid, Review&gt; right) 
    {
        // left - user-group
        // right - restaurant-group
        // exclude the user group 
        // if it contains any restaurant-id of the excluded restaurant-ids
        return left.Any(x =&gt; right.Any(y =&gt; y.Id == x.Id));
    }

    public int GetHashCode(IGrouping&lt;Guid, Review&gt; reviews)
    {
        return 0; // treat all groups equally
    }
}