예제 #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
        private static object PrepareAggregate <T>(IQueryable <T> queryable, Query q)
        {
            var aggregates = q.Aggregates;

            if (aggregates != null && aggregates.Any())
            {
                var  objProps = new Dictionary <DynamicProperty, object>();
                var  groups   = aggregates.GroupBy(g => g.ColumnName);
                Type type     = null;
                foreach (var group in groups)
                {
                    var fieldProps = new Dictionary <DynamicProperty, object>();
                    foreach (var aggregate in group)
                    {
                        var prop     = typeof(T).GetProperty(aggregate.ColumnName);
                        var param    = Expression.Parameter(typeof(T), "s");
                        var selector = aggregate.Aggregate == "count" && (Nullable.GetUnderlyingType(prop.PropertyType) != null)
                            ? Expression.Lambda(Expression.NotEqual(Expression.MakeMemberAccess(param, prop), Expression.Constant(null, prop.PropertyType)), param)
                            : Expression.Lambda(Expression.MakeMemberAccess(param, prop), param);
                        var mi = aggregate.MethodInfo(typeof(T));
                        if (mi == null)
                        {
                            continue;
                        }

                        var val = queryable.Provider.Execute(Expression.Call(null, mi,
                                                                             aggregate.Aggregate == "count" && (Nullable.GetUnderlyingType(prop.PropertyType) == null)
                                ? new[] { queryable.Expression }
                                : new[] { queryable.Expression, Expression.Quote(selector) }));

                        fieldProps.Add(new DynamicProperty(aggregate.Aggregate, typeof(object)), val);
                    }
                    type = DynamicExpression.CreateClass(fieldProps.Keys);
                    var fieldObj = Activator.CreateInstance(type);
                    foreach (var p in fieldProps.Keys)
                    {
                        type.GetProperty(p.Name).SetValue(fieldObj, fieldProps[p], null);
                    }
                    objProps.Add(new DynamicProperty(group.Key, fieldObj.GetType()), fieldObj);
                }

                type = DynamicExpression.CreateClass(objProps.Keys);

                var obj = Activator.CreateInstance(type);

                foreach (var p in objProps.Keys)
                {
                    type.GetProperty(p.Name).SetValue(obj, objProps[p], null);
                }

                return(obj);
            }
            else
            {
                return(null);
            }
        }
예제 #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 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();
        }
예제 #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 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");
        }
예제 #7
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);
        }
예제 #8
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();
        }
예제 #9
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");
        }
예제 #10
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();
        }
예제 #11
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));
        }
예제 #12
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"));
        }
예제 #13
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));
        }
예제 #14
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" }));
        }
예제 #15
0
        public static object Aggregate <T>(this IQueryable <T> queryable, IEnumerable <Aggregator> aggregates)
        {
            if (aggregates == null)
            {
                return(null);
            }

            var aggregators = aggregates as Aggregator[] ?? aggregates.ToArray();

            if (!aggregators.Any())
            {
                return(null);
            }

            var  objProps = new Dictionary <DynamicProperty, object>();
            var  groups   = aggregators.GroupBy(g => g.Field);
            Type type;

            foreach (var group in groups)
            {
                var fieldProps = new Dictionary <DynamicProperty, object>();
                foreach (var aggregate in group)
                {
                    var prop = typeof(T).GetProperty(aggregate.Field);
                    if (prop == null)
                    {
                        throw new InvalidOperationException($"{aggregate.Field} Property does not exists!");
                    }

                    var param    = Expression.Parameter(typeof(T), "s");
                    var selector = aggregate.Aggregate == "count" &&
                                   Nullable.GetUnderlyingType(prop.PropertyType) != null
                        ? Expression.Lambda(
                        Expression.NotEqual(Expression.MakeMemberAccess(param, prop),
                                            Expression.Constant(null, prop.PropertyType)), param)
                        : Expression.Lambda(Expression.MakeMemberAccess(param, prop), param);

                    var mi = aggregate.MethodInfo(typeof(T));
                    if (mi == null)
                    {
                        continue;
                    }

                    var val = queryable.Provider.Execute(Expression.Call(null, mi,
                                                                         aggregate.Aggregate == "count" && Nullable.GetUnderlyingType(prop.PropertyType) == null
                            ? new[] { queryable.Expression }
                            : new[] { queryable.Expression, Expression.Quote(selector) }));

                    fieldProps.Add(new DynamicProperty(aggregate.Aggregate, typeof(object)), val);
                }
                type = DynamicExpression.CreateClass(fieldProps.Keys);
                var fieldObj = Activator.CreateInstance(type);
                foreach (var p in fieldProps.Keys)
                {
                    type.GetProperty(p.Name).SetValue(fieldObj, fieldProps[p], null);
                }
                objProps.Add(new DynamicProperty(group.Key, fieldObj.GetType()), fieldObj);
            }

            type = DynamicExpression.CreateClass(objProps.Keys);

            var obj = Activator.CreateInstance(type);

            foreach (var p in objProps.Keys)
            {
                type.GetProperty(p.Name).SetValue(obj, objProps[p], null);
            }

            return(obj);
        }