public virtual object SelectAggregate(IDataQuery q, string name, IEnumerable <string> args) { name = name?.ToUpper() ?? throw new ArgumentNullException(nameof(name)); if (name != "COUNT" && name != "MIN" && name != "MAX" && name != "AVG" && name != "SUM" && name != "FIRST" && name != "LAST") { return(null); } var firstArg = args.FirstOrDefault(); // if COUNT with no or all selector, return Count if (name == "COUNT" && (string.IsNullOrWhiteSpace(firstArg) || firstArg == "*")) { return(Count(q)); } var query = InitQuery(q) .ApplyConditions(q.Conditions); object result; if (name == "FIRST" || (name == "LAST" && !DataSourceSupportsLast)) { if (q.OrderBy == null) { q.OrderByPrimaryKey(); } var orderBy = q.OrderBy; // if provider doesn't support Last, invert sort and pick first if (name == "LAST") { for (var i = 0; i < q.OrderBy.OrderAsc.Length; i++) { orderBy.OrderAsc[i] = !q.OrderBy.OrderAsc[i]; } } query = query.ApplySorting(orderBy).ApplyLimits(q.Offset, q.Rows); if (string.IsNullOrWhiteSpace(firstArg) || firstArg == "*") { result = query.FirstOrDefault(); } else { result = query.Select(firstArg).FirstOrDefault(); } } else if (name == "LAST" && DataSourceSupportsLast) { query = query.ApplySorting(q.OrderBy).ApplyLimits(q.Offset, q.Rows); if (string.IsNullOrWhiteSpace(firstArg) || firstArg == "*") { result = query.Last(); } else { result = query.Select(firstArg).Last(); } } else { query = query .ApplySorting(q.OrderBy) .ApplyLimits(q.Offset, q.Rows); if (q.OnlyFields != null && q.OnlyFields.Count > 0) { query.GroupBy(firstArg, string.Join(",", q.OnlyFields)); } var n = (name == "AVG") ? "Average" // Method for AVG is Average : name.ToPascalCase(); // ex. SUM => Sum (otherwise Method won't be found) result = query.Aggregate(n, firstArg); } return(result); }