コード例 #1
0
        public void Parse()
        {
            Pieces.Clear();

            var pathPieces = Path.Split('.').ToList();
            var param      = Parameter;
            ExpressionParserPiece parent = null;

            pathPieces.ForEach(pp =>
            {
                var memberExpression = Expression.PropertyOrField(param, pp);
                var current          = new ExpressionParserPiece
                {
                    Type = memberExpression.Type,
                    IsGenericEnumerable = QueryableHelpers.IsGenericEnumerable(memberExpression),
                    EnumerableType      = QueryableHelpers.GetTypeOfEnumerable(memberExpression.Type, false),
                    Parent = parent,
                    Name   = pp
                };

                Pieces.Add(current);

                // for next iteration.
                param  = Expression.Parameter(current.IsGenericEnumerable ? current.EnumerableType : current.Type);
                parent = current;
            });
        }
コード例 #2
0
        private Expression CheckNullOnFirstGroup(ExpressionParserPieceGroup group, Expression currentExpression)
        {
            var path            = string.Join(".", group.Pieces.Select(t => t.Name));
            var whereExpression = QueryableHelpers.CreateConditionExpression(group.Parameter.Type, path,
                                                                             ConditionOperators.NotEqual, null, QueryConvertStrategy.ConvertConstantToComparedPropertyOrField,
                                                                             parameter: group.Parameter, nullChecking: true);

            var whereBodyExpression = (whereExpression as LambdaExpression).Body;

            whereBodyExpression = Expression.Not(whereBodyExpression);



            var        nullType         = currentExpression.Type;
            Expression ifTrueExpression = null;

            if (QueryableHelpers.IsGenericEnumerable(nullType))
            {
                var enumerableType = QueryableHelpers.GetTypeOfEnumerable(nullType, true);
                var listType       = typeof(List <>).MakeGenericType(enumerableType);
                ifTrueExpression = Expression.New(listType);
            }
            else
            {
                ifTrueExpression = Expression.Default(nullType);
            }

            return(Expression.Condition(whereBodyExpression, ifTrueExpression, currentExpression, currentExpression.Type));
        }
コード例 #3
0
        public void TestInheritanceOfListAsGenericEnumerableType()
        {
            var shouldBeTrue = QueryableHelpers.IsGenericEnumerable(typeof(ListOfFoo));

            Assert.IsTrue(shouldBeTrue);
            var type = QueryableHelpers.GetTypeOfEnumerable(typeof(ListOfFoo), true);

            Assert.IsTrue(type == typeof(Foo));
        }
コード例 #4
0
        public void Resolve()
        {
            Result = null;

            // parse the expression.
            if (!Parser.IsParsed)
            {
                Parser.Parse();
            }

            // group the piece by common parameters
            var groups = Parser.GroupBySharedParameters();

            Expression currentExpression = null;

            foreach (var group in groups.Reversed())
            {
                var isLastGroup = groups.IndexOf(group) == groups.Count - 1;

                if (currentExpression == null)
                {
                    var groupExpression       = CompileGroup(group, NullChecking);
                    var groupExpressionLambda = Expression.Lambda(groupExpression, group.Parameter);

                    if (group.Parent == null)
                    {
                        currentExpression = groupExpression;
                        if (NullChecking != false)
                        {
                            currentExpression = CheckNullOnFirstGroup(group, currentExpression);
                        }

                        currentExpression = Expression.Lambda(currentExpression, group.Parameter);
                        continue;
                    }

                    var parent           = group.Parent;
                    var parentExpression = CompileGroup(parent, NullChecking);

                    // check null with where.
                    var isSelectMany = CollectionHandling == SelectCollectionHandling.Flatten && QueryableHelpers.IsGenericEnumerable(groupExpression);
                    if (NullChecking != false)
                    {
                        parentExpression = CheckNullOnEnumerableParent(group, parent, parentExpression, isLastGroup && !isSelectMany);
                    }

                    // the select expression.
                    if (isSelectMany)
                    {
                        var selectType = parent.GroupEnumerableType();
                        var groupExpressionEnumerableType = QueryableHelpers.GetTypeOfEnumerable(groupExpression.Type, true);
                        var selectExpression = Expression.Call(typeof(Enumerable), "SelectMany",
                                                               new Type[] { selectType, groupExpressionEnumerableType },
                                                               parentExpression, groupExpressionLambda);
                        currentExpression = selectExpression;
                    }
                    else
                    {
                        var selectType       = parent.GroupEnumerableType();
                        var selectExpression = Expression.Call(typeof(Enumerable), "Select",
                                                               new Type[] { selectType, groupExpression.Type },
                                                               parentExpression, groupExpressionLambda);
                        currentExpression = selectExpression;
                    }
                }
                else
                {
                    if (group.Parent == null)
                    {
                        if (NullChecking != false)
                        {
                            currentExpression = CheckNullOnFirstGroup(group, currentExpression);
                        }

                        currentExpression = Expression.Lambda(currentExpression, group.Parameter);
                        continue;
                    }

                    var parent           = group.Parent;
                    var parentExpression = CompileGroup(parent, NullChecking);
                    var selectType       = parent.GroupEnumerableType();

                    bool isSelectMany = CollectionHandling == SelectCollectionHandling.Flatten && QueryableHelpers.IsGenericEnumerable(currentExpression);
                    if (NullChecking != false)
                    {
                        parentExpression = CheckNullOnEnumerableParent(group, parent, parentExpression, isLastGroup && !isSelectMany);
                    }

                    if (isSelectMany)
                    {
                        var currentExpressionEnumerableType = QueryableHelpers.GetTypeOfEnumerable(currentExpression.Type, true);
                        var currentExpressionLambda         = Expression.Lambda(currentExpression, group.Parameter);
                        currentExpression = Expression.Call(typeof(Enumerable), "SelectMany",
                                                            new Type[] { selectType, currentExpressionEnumerableType },
                                                            parentExpression, currentExpressionLambda);
                    }
                    else
                    {
                        var currentExpressionLambda = Expression.Lambda(currentExpression, group.Parameter);
                        currentExpression = Expression.Call(typeof(Enumerable), "Select",
                                                            new Type[] { selectType, currentExpression.Type },
                                                            parentExpression, currentExpressionLambda);
                    }
                }
            }

            Result = currentExpression;
        }