예제 #1
0
        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))));
        }
예제 #2
0
        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))));
            }
        }
예제 #3
0
        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));
        }