예제 #1
0
 public void AccessibleTypesCanBeSpecifiedOnEachCall()
 {
     DynamicExpression
     .ParseLambda(typeof(int), typeof(bool), "it != null");
     DynamicExpression.
     ParseLambda(typeof(int), typeof(bool), "it == Int32(MyEnum.Yes)", additionalAllowedTypes: new[] { typeof(MyEnum) });
 }
예제 #2
0
        public void AccessEnumInExpressionWorks()
        {
            var expression = "it == Int32(MyEnum.Yes)";

            var expr = (Expression <Func <int, bool> >)DynamicExpression
                       .ParseLambda(typeof(int), typeof(bool), expression, additionalAllowedTypes: new[] { typeof(MyEnum) });

            expr.ShouldNotBeNull();

            var func = expr.Compile();

            func((int)MyEnum.Yes).ShouldBeTrue();
            func((int)MyEnum.No).ShouldBeFalse();
        }
예제 #3
0
        public void EnumWithoutCastIsConvertedFromInt32ToInt64()
        {
            var expression = "it == MyEnum.Yes";

            var expr = (Expression <Func <long, bool> >)DynamicExpression
                       .ParseLambda(typeof(long), typeof(bool), expression, additionalAllowedTypes: new[] { typeof(MyEnum) });

            expr.ShouldNotBeNull();

            var func = expr.Compile();

            func((int)MyEnum.Yes).ShouldBeTrue();
            func((int)MyEnum.No).ShouldBeFalse();
        }
예제 #4
0
        public void ParseSimpleExpressionWorks()
        {
            var expression = @"x.Length == 4";

            var expr = (Expression <Func <string, bool> >)DynamicExpression
                       .ParseLambda(new[] { Expression.Parameter(typeof(string), "x") }, typeof(bool), expression);

            Assert.NotNull(expr);

            var values = new[] { "bar", "dog", "food", "water" }.AsQueryable();

            var results = values.Where(expr).ToList();

            results.Count.ShouldBe(1);
            results[0].ShouldBe("food");
        }
예제 #5
0
        public void EnumWithoutCastIsConvertedToDestinationType()
        {
            var expression = "it == MyEnum.Yes";

            var expr = (Expression <Func <int, bool> >)DynamicExpression
                       .ParseLambda(typeof(int), typeof(bool), expression, additionalAllowedTypes: new[] { typeof(MyEnum) });

            output.WriteLine("{0}", expr);

            expr.ShouldNotBeNull();

            var func = expr.Compile();

            func((int)MyEnum.Yes).ShouldBeTrue();
            func((int)MyEnum.No).ShouldBeFalse();
        }
예제 #6
0
        public void CanParseFirstOrDefaultExpressionWithoutParams(object[] a, object expectedesult)
        {
            var expression = "FirstOrDefault()";

            var expr = (Expression <Func <IEnumerable <object>, object> >)DynamicExpression
                       .ParseLambda(typeof(IEnumerable <object>), typeof(object), expression);

            output.WriteLine("{0}", expr);

            expr.ShouldNotBeNull();

            var func   = expr.Compile();
            var result = func(a);

            result.ShouldBe(expectedesult);
        }
예제 #7
0
        public void CanParseFirstOrDefaultExpression()
        {
            var expression = "FirstOrDefault(it == \"2\")";

            var expr = (Expression <Func <IEnumerable <string>, string> >)DynamicExpression
                       .ParseLambda(typeof(IEnumerable <string>), typeof(string), expression);

            output.WriteLine("{0}", expr);

            Assert.NotNull(expr);

            var func = expr.Compile();

            func(new[] { "1", "2", "3" }).ShouldBe("2");
            func(new[] { "4" }).ShouldBeNull();
        }
예제 #8
0
        public void ParseSubQueryExpressionWorks()
        {
            var expression = "x.Any(it == 'a')";

            var expr = (Expression <Func <IEnumerable <char>, bool> >)DynamicExpression
                       .ParseLambda(new[] { Expression.Parameter(typeof(IEnumerable <char>), "x") }, typeof(bool), expression);

            Assert.NotNull(expr);

            var values = new[] { "bar", "dog", "food", "water" }.AsQueryable();

            var results = values.Where(expr).ToList();

            results.Count.ShouldBe(2);
            results[0].ShouldBe("bar");
            results[1].ShouldBe("water");
        }
예제 #9
0
        public void CanParseNew()
        {
            var expression = "new(resource.Length alias Len)";

            var parameters = new[]
            {
                Expression.Parameter(typeof(string), "resource"),
            };

            var expr = (Expression <Func <string, object> >)DynamicExpression
                       .ParseLambda(parameters, typeof(object), expression);

            Console.WriteLine(expr);

            Assert.NotNull(expr);

            var func = expr.Compile();
        }
예제 #10
0
        /// <summary>
        /// Correlates the elements of two sequences based on matching keys.
        /// </summary>
        /// <param name="outer">The first sequence to join.</param>
        /// <param name="inner">The sequence to join to the first sequence.</param>
        /// <param name="outerKeySelector">A dynamic function to extract the join key from each element of the first sequence.</param>
        /// <param name="innerKeySelector">A dynamic function to extract the join key from each element of the second sequence.</param>
        /// <param name="resultSelector">A dynamic function to create a result element from two matching elements.</param>
        /// <param name="args">An object array that contains zero or more objects to insert into the predicates as parameters.  Similar to the way String.Format formats strings.</param>
        /// <returns>An <see cref="IQueryable"/> obtained by performing an inner join on two sequences.</returns>
        public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] args)
        {
            //http://stackoverflow.com/questions/389094/how-to-create-a-dynamic-linq-join-extension-method

            if (outer == null)
            {
                throw new ArgumentNullException(nameof(outer));
            }
            if (inner == null)
            {
                throw new ArgumentNullException(nameof(inner));
            }
            if (string.IsNullOrEmpty(outerKeySelector))
            {
                throw new ArgumentNullException(nameof(outerKeySelector));
            }
            if (string.IsNullOrEmpty(innerKeySelector))
            {
                throw new ArgumentNullException(nameof(innerKeySelector));
            }
            if (string.IsNullOrEmpty(resultSelector))
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }


            LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerKeySelector, args);
            LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerKeySelector, args);

            ParameterExpression[] parameters = new ParameterExpression[]
            {
                Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(inner.AsQueryable().ElementType, "inner")
            };

            LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultSelector, args);

            return(outer.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "Join",
                           new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type },
                           outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda))));
        }
예제 #11
0
        /// <summary>
        /// Groups the elements of a sequence according to a specified key string function
        /// and creates a result value from each group and its key.
        /// </summary>
        /// <param name="source">A <see cref="IQueryable"/> whose elements to group.</param>
        /// <param name="keySelector">A string expression to specify the key for each element.</param>
        /// <param name="resultSelector">A string expression to specify a result value from each group.</param>
        /// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters.  Similar to the way String.Format formats strings.</param>
        /// <returns>A <see cref="IQueryable"/> where each element represents a projection over a group and its key.</returns>
        /// <example>
        /// <code>
        /// var groupResult1 = qry.GroupBy("NumberPropertyAsKey", "StringProperty");
        /// var groupResult2 = qry.GroupBy("new (NumberPropertyAsKey, StringPropertyAsKey)", "new (StringProperty1, StringProperty2)");
        /// </code>
        /// </example>
        public static IQueryable GroupBy(this IQueryable source, string keySelector, string resultSelector, object[] args)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (keySelector == null)
            {
                throw new ArgumentNullException(nameof(keySelector));
            }
            if (resultSelector == null)
            {
                throw new ArgumentNullException(nameof(resultSelector));
            }

#if NET35
            if (string.IsNullOrEmpty(keySelector) || keySelector.All(c => Char.IsWhiteSpace(c)))
#else
            if (string.IsNullOrWhiteSpace(keySelector))
#endif
            {
                throw new ArgumentException("Expected non-empty string", nameof(keySelector));
            }

#if NET35
            if (string.IsNullOrEmpty(resultSelector) || resultSelector.All(c => Char.IsWhiteSpace(c)))
#else
            if (string.IsNullOrWhiteSpace(resultSelector))
#endif
            {
                throw new ArgumentException("Expected non-empty string", nameof(resultSelector));
            }

            LambdaExpression keyLambda     = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, args);
            LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, resultSelector, args);

            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))));
        }
예제 #12
0
        public static IQueryable Select(this IQueryable source, string selector, params object[] values)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

            var lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);

            return(source.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "Select",
                           new Type[] { source.ElementType, lambda.Body.Type },
                           source.Expression, Expression.Quote(lambda))));
        }
예제 #13
0
        public void CanParseIsUsingBuiltInType()
        {
            var expression = "resource is Double";

            var parameters = new[]
            {
                Expression.Parameter(typeof(object), "resource"),
            };

            var expr = (Expression <Func <object, bool> >)DynamicExpression
                       .ParseLambda(parameters, typeof(bool), expression);

            Console.WriteLine(expr);

            Assert.NotNull(expr);

            var func = expr.Compile();

            Assert.True(func(2.2));
        }
예제 #14
0
        public void CanParseAs()
        {
            var expression = "(resource as System.String).Length";

            var parameters = new[]
            {
                Expression.Parameter(typeof(object), "resource"),
            };

            var expr = (Expression <Func <object, int> >)DynamicExpression
                       .ParseLambda(parameters, typeof(int), expression);

            Console.WriteLine(expr);

            Assert.NotNull(expr);

            var func = expr.Compile();

            Assert.Equal(5, func("hello"));
        }
예제 #15
0
        public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            var lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);

            return(source.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "Where",
                           new Type[] { source.ElementType },
                           source.Expression, Expression.Quote(lambda))));
        }
예제 #16
0
        public static IQueryable GroupBy(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(source.ElementType, null, keySelector, values);
            LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, 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))));
        }
예제 #17
0
        public void CanParseIs()
        {
            var expression = "resource is System.String";

            var parameters = new[]
            {
                Expression.Parameter(typeof(object), "resource"),
            };

            var expr = (Expression <Func <object, bool> >)DynamicExpression
                       .ParseLambda(parameters, typeof(bool), expression);

            Console.WriteLine(expr);

            Assert.NotNull(expr);

            var func = expr.Compile();

            Assert.True(func("hello"));
            Assert.False(func(2));
        }
예제 #18
0
        /// <summary>
        /// Groups the elements of a sequence according to multiple specified key string functions
        /// and creates a result value from each group (and subgroups) and its key.
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="source">A <see cref="IEnumerable{T}"/> whose elements to group.</param>
        /// <param name="keySelectors"><see cref="string"/> expressions to specify the keys for each element.</param>
        /// <returns>A <see cref="IEnumerable{T}"/> of type <see cref="GroupResult"/> where each element represents a projection over a group, its key, and its subgroups.</returns>
        public static IEnumerable <GroupResult> GroupByMany <TElement>(this IEnumerable <TElement> source, params string[] keySelectors)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (keySelectors == null)
            {
                throw new ArgumentNullException(nameof(keySelectors));
            }

            var selectors = new List <Func <TElement, object> >(keySelectors.Length);

            foreach (var selector in keySelectors)
            {
                LambdaExpression l = DynamicExpression.ParseLambda(typeof(TElement), typeof(object), selector);
                selectors.Add((Func <TElement, object>)l.Compile());
            }

            return(GroupByManyInternal(source, selectors.ToArray(), 0));
        }
        public static Func <T, T, int> CreateComparer <T>(string propertyName, bool ascending)
        {
            string expression;

            if (ascending)
            {
                expression = string.Format("(item1.{0} == item2.{0}) ? 0 : (item1.{0} > item2.{0}) ? 1 : -1", propertyName);
            }
            else
            {
                expression = string.Format("(item2.{0} == item1.{0}) ? 0 : (item2.{0} > item1.{0}) ? 1 : -1", propertyName);
            }
            ParameterExpression[] parameters = new ParameterExpression[]
            {
                Expression.Parameter(typeof(T), "item1"),
                Expression.Parameter(typeof(T), "item2")
            };
            LambdaExpression lambdaExpression = DynamicExpression.ParseLambda(parameters, typeof(int), expression, new object[0]);
            Delegate         @delegate        = lambdaExpression.Compile();

            return(@delegate as Func <T, T, int>);
        }
예제 #20
0
        public void CanParseNestedLambdasWithOuterVariableReference()
        {
            var expression = "resource.Any(allowed.Contains(it_1.Item1))";

            var parameters = new[]
            {
                Expression.Parameter(typeof(Tuple <string>[]), "resource"),
                Expression.Parameter(typeof(string[]), "allowed"),
            };

            var expr = (Expression <Func <Tuple <string>[], string[], bool> >)DynamicExpression
                       .ParseLambda(parameters, typeof(bool), expression);

            Console.WriteLine(expr);

            Assert.NotNull(expr);

            var func = expr.Compile();

            Assert.True(func(new[] { Tuple.Create("1"), Tuple.Create("2") }, new[] { "1", "3" }));
            Assert.False(func(new[] { Tuple.Create("1"), Tuple.Create("2") }, new[] { "3" }));
        }
예제 #21
0
        /// <summary>
        /// Projects each element of a sequence to an <see cref="IQueryable"/> and combines the
        /// resulting sequences into one sequence.
        /// </summary>
        /// <param name="source">A sequence of values to project.</param>
        /// <param name="selector">A projection string expression to apply to each element.</param>
        /// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
        /// <returns>An <see cref="IQueryable"/> whose elements are the result of invoking a one-to-many projection function on each element of the input sequence.</returns>
        public static IQueryable SelectMany(this IQueryable source, string selector, params object[] args)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

#if NET35
            if (string.IsNullOrEmpty(selector) || selector.All(c => Char.IsWhiteSpace(c)))
#else
            if (string.IsNullOrWhiteSpace(selector))
#endif
            {
                throw new ArgumentException("Expected non-empty string", nameof(selector));
            }

            LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, args);

            //Extra help to get SelectMany to work from StackOverflow Answer
            //http://stackoverflow.com/a/3001674/2465182

            //we have to adjust to lambda to return an IEnumerable<T> instead of whatever the actual property is.
            Type inputType      = source.Expression.Type.GetGenericArguments()[0];
            Type resultType     = lambda.Body.Type.GetGenericArguments()[0];
            Type enumerableType = typeof(IEnumerable <>).MakeGenericType(resultType);
            Type delegateType   = typeof(Func <,>).MakeGenericType(inputType, enumerableType);
            lambda = Expression.Lambda(delegateType, lambda.Body, lambda.Parameters);

            return(source.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "SelectMany",
                           new Type[] { source.ElementType, resultType },
                           source.Expression, Expression.Quote(lambda))));
        }
예제 #22
0
        /// <summary>
        /// Groups the elements of a sequence according to a specified key string function
        /// and creates a result value from each group and its key.
        /// </summary>
        /// <param name="source">A <see cref="IQueryable"/> whose elements to group.</param>
        /// <param name="keySelector">A string expression to specify the key for each element.</param>
        /// <param name="resultSelector">A string expression to specify a result value from each group.</param>
        /// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters.  Similar to the way String.Format formats strings.</param>
        /// <returns>A <see cref="IQueryable"/> where each element represents a projection over a group and its key.</returns>
        /// <example>
        /// <code>
        /// var groupResult1 = qry.GroupBy("NumberPropertyAsKey", "StringProperty");
        /// var groupResult2 = qry.GroupBy("new (NumberPropertyAsKey, StringPropertyAsKey)", "new (StringProperty1, StringProperty2)");
        /// </code>
        /// </example>
        public static IQueryable GroupBy(this IQueryable source, string keySelector, string resultSelector, object[] args)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (string.IsNullOrEmpty(keySelector?.Trim()))
            {
                throw new ArgumentNullException(nameof(keySelector));                                            //string.IsNullOrWhiteSpace not available in NET35
            }
            if (string.IsNullOrEmpty(resultSelector?.Trim()))
            {
                throw new ArgumentNullException(nameof(resultSelector));                                               //string.IsNullOrWhiteSpace not available in NET35
            }
            LambdaExpression keyLambda     = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, args);
            LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, resultSelector, args);

            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))));
        }
예제 #23
0
        /// <summary>
        /// Projects each element of a sequence to an <see cref="IQueryable"/>
        /// and invokes a result selector function on each element therein. The resulting
        /// values from each intermediate sequence are combined into a single, one-dimensional
        /// sequence and returned.
        /// </summary>
        /// <param name="source">A sequence of values to project.</param>
        /// <param name="collectionSelector">A projection function to apply to each element of the input sequence.</param>
        /// <param name="resultSelector">A projection function to apply to each element of each intermediate sequence.</param>
        /// <param name="collectionSelectorArgs">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
        /// <param name="resultSelectorArgs">An object array that contains zero or more objects to insert into the predicate as parameters. Similar to the way String.Format formats strings.</param>
        /// <returns>
        /// An <see cref="IQueryable"/> whose elements are the result of invoking the one-to-many
        /// projection function <paramref name="collectionSelector"/> on each element of source and then mapping
        /// each of those sequence elements and their corresponding source element to a result element.
        /// </returns>
        public static IQueryable SelectMany(this IQueryable source, string collectionSelector, string resultSelector, object[] collectionSelectorArgs = null, object[] resultSelectorArgs = null)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (string.IsNullOrEmpty(collectionSelector?.Trim()))
            {
                throw new ArgumentNullException(nameof(collectionSelector));                                                   //string.IsNullOrWhiteSpace not available in NET35
            }
            if (string.IsNullOrEmpty(resultSelector?.Trim()))
            {
                throw new ArgumentNullException(nameof(resultSelector));                                               //string.IsNullOrWhiteSpace not available in NET35
            }
            LambdaExpression sourceSelectLambda = DynamicExpression.ParseLambda(source.ElementType, null, collectionSelector, collectionSelectorArgs);

            //we have to adjust to lambda to return an IEnumerable<T> instead of whatever the actual property is.
            Type sourceLambdaInputType      = source.Expression.Type.GetGenericArguments()[0];
            Type sourceLambdaResultType     = sourceSelectLambda.Body.Type.GetGenericArguments()[0];
            Type sourceLambdaEnumerableType = typeof(IEnumerable <>).MakeGenericType(sourceLambdaResultType);
            Type sourceLambdaDelegateType   = typeof(Func <,>).MakeGenericType(sourceLambdaInputType, sourceLambdaEnumerableType);

            sourceSelectLambda = Expression.Lambda(sourceLambdaDelegateType, sourceSelectLambda.Body, sourceSelectLambda.Parameters);

            //we have to create additional lambda for result selection
            ParameterExpression xParameter = Expression.Parameter(source.ElementType, "x");
            ParameterExpression yParameter = Expression.Parameter(sourceLambdaResultType, "y");

            LambdaExpression resultSelectLambda     = DynamicExpression.ParseLambda(new[] { xParameter, yParameter }, null, resultSelector, resultSelectorArgs);
            Type             resultLambdaResultType = resultSelectLambda.Body.Type;

            return(source.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "SelectMany",
                           new Type[] { source.ElementType, sourceLambdaResultType, resultLambdaResultType },
                           source.Expression, Expression.Quote(sourceSelectLambda), Expression.Quote(resultSelectLambda))));
        }
        /// <summary>
        /// Projects each element of a sequence to an <see cref="IQueryable"/> and combines the
        /// resulting sequences into one sequence.
        /// </summary>
        /// <param name="source">A sequence of values to project.</param>
        /// <param name="selector">A projection string expression to apply to each element.</param>
        /// <param name="args">An object array that contains zero or more objects to insert into the predicate as parameters.  Similiar to the way String.Format formats strings.</param>
        /// <returns>An <see cref="IQueryable"/> whose elements are the result of invoking a one-to-many projection function on each element of the input sequence.</returns>
        public static IQueryable SelectMany(this IQueryable source, string selector, params object[] args)
        {
            Validate.Argument(source, "source").IsNotNull().Check()
            .Argument(selector, "selector").IsNotNull().IsNotEmpty().IsNotWhiteSpace().Check();

            LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, args);

            //Extra help to get SelectMany to work from StackOverflow Answer
            //http://stackoverflow.com/a/3001674/2465182

            //we have to adjust to lambda to return an IEnumerable<T> instead of whatever the actual property is.
            Type inputType      = source.Expression.Type.GetGenericArguments()[0];
            Type resultType     = lambda.Body.Type.GetGenericArguments()[0];
            Type enumerableType = typeof(IEnumerable <>).MakeGenericType(resultType);
            Type delegateType   = typeof(Func <,>).MakeGenericType(inputType, enumerableType);

            lambda = Expression.Lambda(delegateType, lambda.Body, lambda.Parameters);

            return(source.Provider.CreateQuery(
                       Expression.Call(
                           typeof(Queryable), "SelectMany",
                           new Type[] { source.ElementType, resultType },
                           source.Expression, Expression.Quote(lambda))));
        }
예제 #25
0
 public static Expression <Func <T, S> > ParseLambda <T, S>(string expression, params object[] values)
 {
     return((Expression <Func <T, S> >)DynamicExpression.ParseLambda(typeof(T), typeof(S), expression, values));
 }