internal static IQueryable GetSubGroupsAndCountsQueryable(this IQueryable queryable, string subGroupBy, bool sortGroupBy, ListSortDirection direction) { // Create GroupBy Type queryableElementType = queryable.ElementType; ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(queryableElementType, "") }; MemberExpression memberExpression = QueryableExtensions.GenerateMemberExpression(parameters[0], subGroupBy); LambdaExpression groupByLambdaExpression = Expression.Lambda(memberExpression, parameters); MethodCallExpression groupByMethodExpression = Expression.Call( typeof(Queryable), "GroupBy", new Type[] { queryableElementType, groupByLambdaExpression.Body.Type }, new Expression[] { queryable.Expression, Expression.Quote(groupByLambdaExpression) }); IQueryable groupedResult = queryable.Provider.CreateQuery(groupByMethodExpression); if (sortGroupBy) { groupedResult = groupedResult.OrderByKey(direction == ListSortDirection.Ascending); } ParameterExpression[] groupedParameters = new ParameterExpression[] { System.Linq.Expressions.Expression.Parameter(groupedResult.ElementType, "") }; MemberExpression keyMemberExpression = MemberExpression.Property(groupedParameters[0], "Key"); MethodCallExpression countCallExpression = MethodCallExpression.Call(typeof(Enumerable), "Count", new Type[] { queryableElementType }, groupedParameters); QueryableGroupNameCountPairInfo queryableGroupNameCountPairInfo = QueryableExtensions.QueryableGroupNameCountPairInfos.GetInfosForType(memberExpression.Type); Expression[] newExpressionArguments = new Expression[2] { keyMemberExpression, countCallExpression }; NewExpression newExpression = NewExpression.New( queryableGroupNameCountPairInfo.ConstructorInfo, newExpressionArguments, new MemberInfo[] { queryableGroupNameCountPairInfo.KeyPropertyInfo, queryableGroupNameCountPairInfo.CountPropertyInfo }); LambdaExpression finalLambdaExpression = System.Linq.Expressions.Expression.Lambda(newExpression, groupedParameters); MethodCallExpression finalSelectExpression = System.Linq.Expressions.Expression.Call( typeof(Queryable), "Select", new Type[] { groupedResult.ElementType, finalLambdaExpression.Body.Type }, new System.Linq.Expressions.Expression[] { groupedResult.Expression, System.Linq.Expressions.Expression.Quote(finalLambdaExpression) }); return(groupedResult.Provider.CreateQuery(finalSelectExpression)); }