/// <summary> /// Implement the Count-Distinct aggregation method /// </summary> /// <param name="elementType">The type of entities</param> /// <param name="query">The collection</param> /// <param name="transformation">The transformation clause created by the parser</param> /// <param name="propertyToAggregateExpression">Projection Expression that defines access to the property to aggregate</param> /// <param name="parameters">A list of string parameters sent to the aggregation method</param> /// <returns>The Sum result</returns> public override object DoAggregatinon(Type elementType, IQueryable collection, ApplyAggregateClause transformation, LambdaExpression propertyToAggregateExpression, params string[] parameters) { var propertyType = GetAggregatedPropertyType(elementType, transformation.AggregatableProperty); var selectedValues = GetSelectedValues(elementType, collection, transformation, propertyToAggregateExpression); //call: (selected.AsQueryable() as IQueryable<double>).Ditinct(); var distinct = ExpressionHelpers.Distinct(propertyType, selectedValues); try { //call: (distinct.AsQueryable() as IQueryable<double>).Count(); return(ExpressionHelpers.Count(propertyType, distinct)); } catch (TargetInvocationException) { //salve a problem in mongo that throw the error "No further operators may follow Distinct in a LINQ query." when trying to construct the expression tree. distinct = ExpressionHelpers.Cast(propertyType, distinct.AllElements().AsQueryable()); return(ExpressionHelpers.Count(propertyType, distinct)); } }
/// <summary> /// Execute group-by without aggregation on the results. /// </summary> /// <param name="query">The collection to group.</param> /// <param name="maxResults">The max number of elements in a result set.</param> /// <param name="transformation">The group-by transformation as <see cref="ApplyGroupbyClause"/>.</param> /// <param name="keyType">The key type to group by.</param> /// <param name="propertiesToGroupByExpressions">Lambda expression that represents access to the properties to group by.</param> /// <returns>The results of the group by transformation as <see cref="IQueryable"/>.</returns> public IQueryable DoGroupBy(IQueryable query, int maxResults, ApplyGroupbyClause transformation, Type keyType, IEnumerable <LambdaExpression> propertiesToGroupByExpressions) { var propToGroupBy = (propertiesToGroupByExpressions != null) ? propertiesToGroupByExpressions.ToArray() : null; var keySelector = this.GetGroupByProjectionLambda(transformation.SelectedStatements.ToArray(), keyType, propToGroupBy); object comparer = keyType.GetProperty("ComparerInstance").GetValue(null); var results = ExpressionHelpers.GroupBy(query, keySelector, this.Context.ElementClrType, keyType, comparer); var keys = this.GetGroupingKeys(results, keyType, this.Context.ElementClrType); // if group by is not supported in this IQueriable provider convert the grouping into memory implementation object convertedResult = null; int numberOfTempResults; if (QueriableProviderAdapter.ConvertionIsRequiredAsExpressionIfNotSupported(keys, maxResults, out convertedResult, out numberOfTempResults)) { keys = convertedResult as IQueryable; } var keysToReturn = ExpressionHelpers.Distinct(keyType, keys); return(keysToReturn); }