public static IQueryable GroupBy <T>(this IQueryable source, string keySelector, string elementSelector, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (elementSelector == null) { throw new ArgumentNullException("elementSelector"); } LambdaExpression keyLambda = DynamicExpression.ParseLambda <T>(source.ElementType, null, keySelector, true, values); LambdaExpression elementLambda = DynamicExpression.ParseLambda <T>(source.ElementType, null, elementSelector, true, values); return(source.Provider.CreateQuery( Expression.Call( typeof(Queryable), "GroupBy", new Type[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type }, source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)))); }
public static IQueryable Where <T>(this IQueryable source, string predicate, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } LambdaExpression lambda = DynamicExpression.ParseLambda <T>(source.ElementType, typeof(bool), predicate, true, values); if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(T)) { //source list is DynamicNode and the lambda returns a Func<object> IQueryable <T> typedSource = source as IQueryable <T>; var compiledFunc = lambda.Compile(); Func <T, object> func = null; Func <T, bool> boolFunc = null; if (compiledFunc is Func <T, object> ) { func = (Func <T, object>)compiledFunc; } if (compiledFunc is Func <T, bool> ) { boolFunc = (Func <T, bool>)compiledFunc; } return(typedSource.Where(delegate(T node) { object value = -1; //value = func(node); //I can't figure out why this is double func<>'d try { if (func != null) { var firstFuncResult = func(node); if (firstFuncResult is Func <T, object> ) { value = (firstFuncResult as Func <T, object>)(node); } if (firstFuncResult is Func <T, bool> ) { value = (firstFuncResult as Func <T, bool>)(node); } if (firstFuncResult is bool) { return (bool)firstFuncResult; } if (value is bool) { return (bool)value; } } if (boolFunc != null) { return boolFunc(node); } return false; } catch (Exception ex) { Trace.WriteLine(ex.Message); return false; } }).AsQueryable()); } else { return(source.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, Expression.Quote(lambda)))); } }
public static IQueryable OrderBy <T>(this IQueryable source, string ordering, Func <Type> getDynamicListTypeCallback, params object[] values) { if (source == null) { throw new ArgumentNullException("source"); } if (ordering == null) { throw new ArgumentNullException("ordering"); } IQueryable <T> typedSource = source as IQueryable <T>; if (!ordering.Contains(",")) { bool descending = false; if (ordering.IndexOf(" descending", StringComparison.CurrentCultureIgnoreCase) >= 0) { ordering = ordering.Replace(" descending", ""); descending = true; } if (ordering.IndexOf(" desc", StringComparison.CurrentCultureIgnoreCase) >= 0) { ordering = ordering.Replace(" desc", ""); descending = true; } LambdaExpression lambda = DynamicExpression.ParseLambda <T>(source.ElementType, typeof(object), ordering, false, values); if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(T)) { //source list is DynamicNode and the lambda returns a Func<object> Func <T, object> func = (Func <T, object>)lambda.Compile(); //get the values out var query = typedSource.ToList().ConvertAll(item => new { node = item, key = EvaluateDynamicNodeFunc(item, func) }); if (query.Count == 0) { return(source); } var types = from i in query group i by i.key.GetType() into g where g.Key != typeof(DynamicNull) orderby g.Count() descending select new { g, Instances = g.Count() }; var dominantType = types.First().g.Key; // NH - add culture dependencies StringComparer comp = StringComparer.Create(CultureInfo.CurrentCulture, true); if (!descending) { // if the dominant type is a string we'll ensure that strings are sorted based on culture settings on node if (dominantType.FullName == "System.String") { return(query.OrderBy(item => item.key.ToString(), comp).Select(item => item.node).AsQueryable()); } else { return(query.OrderBy(item => GetObjectAsTypeOrDefault(item.key, dominantType)).Select(item => item.node).AsQueryable()); } } else { if (dominantType.FullName == "System.String") { return(query.OrderByDescending(item => item.key.ToString(), comp).Select(item => item.node).AsQueryable()); } else { return(query.OrderByDescending(item => GetObjectAsTypeOrDefault(item.key, dominantType)).Select(item => item.node).AsQueryable()); } } } } bool isDynamicNodeList = false; if (typedSource != null) { isDynamicNodeList = true; } ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(source.ElementType, "") }; var parser = new ExpressionParser <T>(parameters, ordering, values, false); IEnumerable <DynamicOrdering> orderings = parser.ParseOrdering(); Expression queryExpr = source.Expression; string methodAsc = "OrderBy"; string methodDesc = "OrderByDescending"; foreach (DynamicOrdering o in orderings) { if (!isDynamicNodeList) { queryExpr = Expression.Call( typeof(Queryable), o.Ascending ? methodAsc : methodDesc, new Type[] { source.ElementType, o.Selector.Type }, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters))); } else { //reroute each stacked Expression.Call into our own methods that know how to deal //with DynamicNode queryExpr = Expression.Call( getDynamicListTypeCallback(), o.Ascending ? methodAsc : methodDesc, null, queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)) ); } methodAsc = "ThenBy"; methodDesc = "ThenByDescending"; } if (isDynamicNodeList) { return(typedSource.Provider.CreateQuery(queryExpr)); } return(source.Provider.CreateQuery(queryExpr)); }