예제 #1
0
            public static T FindIn(Expression expression)
            {
                if (expression == null)
                {
                    return(default(T));
                }
                var finder = new ConstantFinder <T>();

                finder.Visit(expression);
                return(finder.Result);
            }
예제 #2
0
        public IQueryable <TElement> CreateQuery <TElement>(Expression expression)
        {
            if (!(expression is MethodCallExpression mc))
            {
                throw new ArgumentException("Invalid expression", nameof(expression));
            }
            var queryable = ConstantFinder <IQueryable <TSource> > .FindIn(mc.Arguments[0]);

            if (queryable == null)
            {
                throw new InvalidOperationException("Cannot find source.");
            }

            if (mc.Method.TryFindMethod(out var method))
            {
                var arguments = mc.Arguments.Select(x =>
                                                    LambdaFinder.FindIn(x) ?? ConstantFinder <object> .FindIn(x)).ToArray();
                return((IQueryable <TElement>)method.Invoke(null, arguments));
            }

            var source     = new Lazy <IEnumerable <TSource> >(() => (queryable as IQueryableCollection <TSource>)?.Source ?? queryable);
            var collection = new Lazy <IReadOnlyObservableCollection <TSource> >(() => source.Value as IReadOnlyObservableCollection <TSource>);
            var list       = new Lazy <IReadOnlyObservableList <TSource> >(() => source.Value as IReadOnlyObservableList <TSource>);

            switch (mc.Method.Name)
            {
            case "OfType" when mc.Arguments.Count == 1 && collection.Value != null:
                return(list.Value != null
                        ? new CastingReadOnlyObservableList <TSource, TElement>(list.Value.ListWhere(x => x is TElement)).AsQueryableCollection()
                        : new CastingReadOnlyObservableCollection <TSource, TElement>(source.Value.ListWhere(x => x is TElement)).AsQueryableCollection());

            case "Cast" when mc.Arguments.Count == 1 && collection.Value != null:
                return(list.Value != null
                        ? new CastingReadOnlyObservableList <TSource, TElement>(list.Value).AsQueryableCollection()
                        : new CastingReadOnlyObservableCollection <TSource, TElement>(collection.Value).AsQueryableCollection());
            }

            var updater = new QueryModifier();

            expression = updater.Visit(expression);
            if (updater.Source == null)
            {
                throw new InvalidOperationException();
            }
            var result = updater.Source.Provider.CreateQuery <TElement>(expression);

            return(result);
        }
예제 #3
0
        public TResult Execute <TResult>(Expression expression)
        {
            if (expression is MethodCallExpression mc)
            {
                if (mc.Method.TryFindMethod(out var method))
                {
                    var arguments = mc.Arguments.Select(x =>
                                                        LambdaFinder.FindIn(x) ?? ConstantFinder <object> .FindIn(x)).ToArray();
                    return((TResult)method.Invoke(null, arguments));
                }
            }

            var updater = new QueryModifier();

            expression = updater.Visit(expression);
            if (updater.Source == null)
            {
                throw new InvalidOperationException();
            }
            var result = updater.Source.Provider.Execute <TResult>(expression);

            return(result);
        }