using PoweredSoft.DynamicLinq.Fluent; using PoweredSoft.DynamicLinq.Helpers; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace PoweredSoft.DynamicLinq { public static class QueryableExtensions { public static IQueryable Where(this IQueryable query, string path, ConditionOperators conditionOperator, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) { query = query.Query(qb => qb.Compare(path, conditionOperator, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision)); return query; } public static IQueryable Where(this IQueryable query, string path, ConditionOperators conditionOperator, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) { query = query.Query(qb => qb.Compare(path, conditionOperator, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision)); return query; } public static IQueryable Where(this IQueryable query, Action callback) => query.Query(callback); public static IQueryable Query(this IQueryable query, Action callback) { var queryBuilder = new WhereBuilder(query); callback(queryBuilder); var ret = queryBuilder.Build(); return (IQueryable)ret; } // non generics were missing. public static IQueryable Where(this IQueryable query, Action callback) => query.Query(callback); public static IQueryable Query(this IQueryable query, Action callback) { var queryBuilder = new WhereBuilder(query); callback(queryBuilder); var ret = queryBuilder.Build(); return ret; } // generic. public static IQueryable OrderBy(this IQueryable query, string path, QueryOrderByDirection direction, bool append) { IQueryable queryable = query; query = queryable.OrderBy(path, direction, append) as IQueryable; return query; } public static IQueryable OrderBy(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Ascending, false); public static IQueryable OrderByDescending(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Descending, false); public static IQueryable ThenBy(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Ascending, true); public static IQueryable ThenByDescending(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Descending, true); // non generic. public static IQueryable OrderBy(this IQueryable query, string path, QueryOrderByDirection direction, bool append) { var qb = new OrderByBuilder(query); qb.OrderBy(path, direction, append); var ret = qb.Build(); return ret; } public static IQueryable OrderBy(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Ascending, false); public static IQueryable OrderByDescending(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Descending, false); public static IQueryable ThenBy(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Ascending, true); public static IQueryable ThenByDescending(this IQueryable query, string path) => query.OrderBy(path, QueryOrderByDirection.Descending, true); // group by public static IQueryable GroupBy(this IQueryable query, string path) => QueryableHelpers.GroupBy(query, typeof(T), path); public static IQueryable GroupBy(this IQueryable query, Type type, string path) => QueryableHelpers.GroupBy(query, type, path); public static IQueryable GroupBy(this IQueryable query, Action callback) => query.GroupBy(typeof(T), callback); public static IQueryable GroupBy(this IQueryable query, Type type, Action callback) { var groupBuilder = new GroupBuilder(query); callback(groupBuilder); var ret = groupBuilder.Build(); return ret; } public static IQueryable Select(this IQueryable query, Action callback) { var sb = new SelectBuilder(query); callback(sb); var ret = sb.Build(); return ret; } public static List ToObjectList(this IQueryable query) { // Expression call tolist? var ret = new List(); foreach (var o in query) ret.Add(o); return ret; } public static List ToDynamicList(this IQueryable query) { var ret = new List(); foreach (var o in query) ret.Add(o); return ret; } public static List ToDynamicClassList(this IQueryable query) { if (!typeof(DynamicClass).IsAssignableFrom(query.ElementType)) throw new Exception($"{query.ElementType} does not inherit DynamicClass"); var ret = query.Cast().ToList(); return ret; } private static MethodInfo _internalCount = typeof(QueryableExtensions).GetMethod(nameof(QueryableExtensions.InternalCount), BindingFlags.Static | BindingFlags.NonPublic); private static int InternalCount(IQueryable q) => System.Linq.Queryable.Count(q); public static int Count(this IQueryable query) => (int)_internalCount.MakeGenericMethod(query.ElementType).Invoke(null, new object[] {query}); private static MethodInfo _internalLongCount = typeof(QueryableExtensions).GetMethod(nameof(QueryableExtensions.InternalLongCount), BindingFlags.Static | BindingFlags.NonPublic); private static long InternalLongCount(IQueryable q) => System.Linq.Queryable.LongCount(q); public static long LongCount(this IQueryable query) { var method =_internalLongCount.MakeGenericMethod(query.ElementType); var result = method.Invoke(null, new object[] {query}); return (long) result; } public static IQueryable EmptyGroupBy(this IQueryable queryable, Type underlyingType) { var parameter = Expression.Parameter(underlyingType); var genericMethod = Constants.GroupByMethod.MakeGenericMethod(underlyingType, typeof(bool)); var trueConstant = Expression.Constant(true); var lambda = Expression.Lambda(trueConstant, parameter); var groupByExpression = Expression.Call(genericMethod, queryable.Expression, lambda); var result = queryable.Provider.CreateQuery(groupByExpression); return result; } } }