예제 #1
0
        public Expression ApplyFilter(Expression source, FilterClause filterClause)
        {
            if (filterClause == null)
            {
                return(source);
            }

            Expression       e      = _visitor.TranslateNode(filterClause.Expression);
            LambdaExpression lambda = Expression.Lambda(e, Parameter);

            MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(ParameterType);

            return(Expression.Call(whereMethodInfo, source, lambda));
        }
예제 #2
0
        public Expression ApplyNavigation(Expression source, IEnumerable <OeParseNavigationSegment> parseNavigationSegments)
        {
            if (parseNavigationSegments == null)
            {
                return(source);
            }

            Type sourceItemType = OeExpressionHelper.GetCollectionItemType(source.Type);

            foreach (OeParseNavigationSegment parseNavigationSegment in parseNavigationSegments)
            {
                Type selectType;
                ParameterExpression parameter;
                Expression          e;
                if (parseNavigationSegment.NavigationSegment == null) //EntitySetSegment
                {
                    parameter  = Parameter;
                    e          = source;
                    selectType = sourceItemType;
                }
                else
                {
                    parameter = Expression.Parameter(sourceItemType);
                    PropertyInfo navigationClrProperty = sourceItemType.GetTypeInfo().GetProperty(parseNavigationSegment.NavigationSegment.NavigationProperty.Name);
                    e = Expression.MakeMemberAccess(parameter, navigationClrProperty);

                    MethodInfo selectMethodInfo;
                    selectType = OeExpressionHelper.GetCollectionItemType(e.Type);
                    if (selectType == null)
                    {
                        selectType       = e.Type;
                        selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceItemType, selectType);
                    }
                    else
                    {
                        selectMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(sourceItemType, selectType);
                    }

                    LambdaExpression lambda = Expression.Lambda(e, parameter);
                    source = Expression.Call(selectMethodInfo, source, lambda);
                }

                if (parseNavigationSegment.Filter != null)
                {
                    var visitor = new OeQueryNodeVisitor(_visitor, Expression.Parameter(selectType));
                    e = visitor.TranslateNode(parseNavigationSegment.Filter.Expression);
                    LambdaExpression lambda = Expression.Lambda(e, visitor.Parameter);

                    MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(selectType);
                    source = Expression.Call(whereMethodInfo, source, lambda);
                }

                _entityType    = selectType;
                sourceItemType = selectType;
            }

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(_entityType), _visitor.Constans);
            return(source);
        }
예제 #3
0
        public Expression ApplyNavigation(Expression source, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments)
        {
            if (parseNavigationSegments == null)
            {
                return(source);
            }

            Type sourceItemType = OeExpressionHelper.GetCollectionItemType(source.Type);

            foreach (OeParseNavigationSegment parseNavigationSegment in parseNavigationSegments)
            {
                Type selectType;
                ParameterExpression parameter;
                Expression          e;
                if (parseNavigationSegment.NavigationSegment == null) //EntitySetSegment, KeySegment
                {
                    parameter  = Visitor.Parameter;
                    e          = source;
                    selectType = sourceItemType;
                }
                else
                {
                    parameter = Expression.Parameter(sourceItemType);
                    PropertyInfo navigationClrProperty = sourceItemType.GetPropertyIgnoreCase(parseNavigationSegment.NavigationSegment.NavigationProperty);
                    e = Expression.MakeMemberAccess(parameter, navigationClrProperty);

                    MethodInfo selectMethodInfo;
                    selectType = OeExpressionHelper.GetCollectionItemTypeOrNull(e.Type) ?? e.Type;
                    if (selectType == e.Type)
                    {
                        selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceItemType, selectType);
                    }
                    else
                    {
                        selectMethodInfo = OeMethodInfoHelper.GetSelectManyMethodInfo(sourceItemType, selectType);
                    }

                    LambdaExpression lambda = Expression.Lambda(e, parameter);
                    source = Expression.Call(selectMethodInfo, source, lambda);
                }

                if (parseNavigationSegment.Filter != null)
                {
                    var visitor = new OeQueryNodeVisitor(Visitor, Expression.Parameter(selectType));
                    e = visitor.TranslateNode(parseNavigationSegment.Filter.Expression);
                    LambdaExpression lambda = Expression.Lambda(e, visitor.Parameter);

                    MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(selectType);
                    source = Expression.Call(whereMethodInfo, source, lambda);
                }

                sourceItemType = selectType;
            }

            Visitor.ChangeParameterType(Expression.Parameter(sourceItemType));
            return(source);
        }
예제 #4
0
 private void BuildCompute(ComputeClause computeClause)
 {
     foreach (ComputeExpression computeExpression in computeClause.ComputedItems)
     {
         Expression        expression       = _visitor.TranslateNode(computeExpression.Expression);
         IEdmTypeReference edmTypeReference = OeEdmClrHelper.GetEdmTypeReference(_model, expression.Type);
         _selectItemInfos.Add(new SelectItemInfo(new ComputeProperty(computeExpression.Alias, edmTypeReference), expression));
     }
 }
            public Expression ApplyOrderBy(Expression source, OrderByClause orderByClause, out bool isInsertedOrderByMethod)
            {
                isInsertedOrderByMethod = _isInsertedOrderByMethod;
                if (orderByClause == null)
                {
                    return(source);
                }

                Expression keySelector = null;

                if (!_isInsertedOrderByMethod)
                {
                    var tupleProperty = new OePropertyTranslator(source);
                    _visitor.TuplePropertyByEdmProperty = tupleProperty.Build;

                    if (OeExpressionHelper.IsTupleType(_visitor.Parameter.Type))
                    {
                        var propertyNode = (SingleValuePropertyAccessNode)orderByClause.Expression;
                        keySelector = tupleProperty.Build(_visitor.Parameter, propertyNode.Property);
                    }

                    if (keySelector == null)
                    {
                        keySelector = _visitor.TranslateNode(orderByClause.Expression);
                    }
                }

                if (keySelector == null)
                {
                    var propertyNode = orderByClause.Expression as SingleValuePropertyAccessNode;
                    if (propertyNode == null)
                    {
                        throw new NotSupportedException("rewrite expression support only sort by property");
                    }

                    IEdmType edmSplitType;
                    if (propertyNode.Source is SingleNavigationNode navigationNode)
                    {
                        while (navigationNode.Source is SingleNavigationNode)
                        {
                            navigationNode = navigationNode.Source as SingleNavigationNode;
                        }
                        edmSplitType = navigationNode.NavigationProperty.DeclaringType;
                    }
                    else
                    {
                        edmSplitType = propertyNode.Property.DeclaringType;
                    }

                    isInsertedOrderByMethod = true;
                    return(InsertOrderByMethod(source, orderByClause, edmSplitType));
                }

                return(GetOrderByExpression(source, _visitor.Parameter, orderByClause.Direction, keySelector));
            }
            private Expression InsertOrderByMethod(Expression source, OrderByClause orderByClause, IEdmType edmSplitType)
            {
                Type       sourceItemType    = _visitor.EdmModel.GetClrType(edmSplitType);
                Type       sourceTypeGeneric = _isInsertedOrderByMethod ? typeof(IOrderedEnumerable <>) : typeof(IEnumerable <>);
                var        splitterVisitor   = new OeExpressionSplitterVisitor(sourceTypeGeneric.MakeGenericType(sourceItemType));
                Expression beforeExpression  = splitterVisitor.GetBefore(source);

                var        visitor     = new OeQueryNodeVisitor(_visitor.EdmModel, Expression.Parameter(sourceItemType), _visitor.Constans);
                Expression keySelector = visitor.TranslateNode(orderByClause.Expression);
                Expression orderByCall = GetOrderByExpression(beforeExpression, visitor.Parameter, orderByClause.Direction, keySelector);

                return(splitterVisitor.Join(orderByCall));
            }
예제 #7
0
        private MethodCallExpression ApplyCompute(Expression source, ComputeTransformationNode transformation)
        {
            var expressions = new List <Expression>();

            Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type);
            ParameterExpression sourceParameter = Expression.Parameter(sourceType);

            if (_aggProperties.Count > 0)
            {
                var callExpression = (MethodCallExpression)source;
                source = callExpression.Arguments[0];
                var aggLambda = (LambdaExpression)callExpression.Arguments[1];
                expressions.AddRange(((NewExpression)aggLambda.Body).Arguments);

                sourceType      = OeExpressionHelper.GetCollectionItemType(source.Type);
                sourceParameter = aggLambda.Parameters[0];
            }

            OeQueryNodeVisitor visitor = CreateVisitor(sourceParameter);

            if (_aggProperties.Count > 0)
            {
                visitor.TuplePropertyByAliasName = new ComputeAliasNameResolver(_aggProperties, expressions).GetTuplePropertyByAliasName;
            }

            foreach (ComputeExpression computeExpression in transformation.Expressions)
            {
                Expression expression = visitor.TranslateNode(computeExpression.Expression);
                expressions.Add(expression);

                _aggProperties.Add(CreateEdmProperty(visitor.EdmModel, expression.Type, computeExpression.Alias, false));
            }

            NewExpression    newExpression    = OeExpressionHelper.CreateTupleExpression(expressions);
            MethodInfo       selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceParameter.Type, newExpression.Type);
            LambdaExpression lambda           = Expression.Lambda(newExpression, sourceParameter);

            return(Expression.Call(selectMethodInfo, source, lambda));
        }
        private static Expression CreateFilterExpression(Expression source, OeQueryNodeVisitor visitor, bool isDatabaseNullHighestValue, OrderProperty[] orderProperties)
        {
            var tupleProperty = new OePropertyTranslator(source);

            Expression filter = null;

            for (int i = 0; i < orderProperties.Length; i++)
            {
                BinaryExpression eqFilter = null;
                for (int j = 0; j < i; j++)
                {
                    MemberExpression   propertyExpression  = orderProperties[j].PropertyExpression;
                    ConstantExpression parameterExpression = orderProperties[j].ParmeterExpression;
                    BinaryExpression   eq = Expression.Equal(propertyExpression, parameterExpression);

                    if (OeExpressionHelper.IsNullable(propertyExpression))
                    {
                        UnaryExpression  typedNull = Expression.Convert(OeConstantToVariableVisitor.NullConstantExpression, parameterExpression.Type);
                        BinaryExpression isNull    = Expression.Equal(parameterExpression, typedNull);
                        eq = Expression.OrElse(eq, isNull);
                    }

                    eqFilter = eqFilter == null ? eq : Expression.AndAlso(eqFilter, eq);
                }

                orderProperties[i].PropertyExpression = (MemberExpression)visitor.TranslateNode(orderProperties[i].PropertyNode);
                if (orderProperties[i].PropertyExpression == null)
                {
                    orderProperties[i].PropertyExpression = tupleProperty.Build(visitor.Parameter, orderProperties[i].PropertyNode.Property);
                }
                BinaryExpression ge = CreateBinaryExpression(visitor, isDatabaseNullHighestValue, ref orderProperties[i]);

                eqFilter = eqFilter == null ? ge : Expression.AndAlso(eqFilter, ge);
                filter   = filter == null ? eqFilter : Expression.OrElse(filter, eqFilter);
            }
            return(filter);
        }
        public static Expression Bind(OeQueryNodeVisitor visitor, SingleValueFunctionCallNode nodeIn)
        {
            var expressions = new List <Expression>(2);

            foreach (QueryNode node in nodeIn.Parameters)
            {
                expressions.Add(visitor.TranslateNode(node));
            }

            if (OeExpressionHelper.IsNullable(expressions[0]))
            {
                MethodInfo           getValueOrDefault = expressions[0].Type.GetMethod("GetValueOrDefault", Type.EmptyTypes);
                MethodCallExpression callExpression    = Expression.Call(expressions[0], getValueOrDefault);
                expressions[0] = callExpression;
            }

            bool   isProperty = false;
            string name;

            switch (nodeIn.Name)
            {
            case "cast":
                return(CastFunction(nodeIn, expressions));

            case "ceiling":
                return(CeilingFunction(expressions));

            case "concat":
                return(ConcatFunction(expressions));

            case "contains":
                name = "Contains";
                break;

            case "day":
                name       = "Day";
                isProperty = true;
                break;

            case "endswith":
                name = "EndsWith";
                break;

            case "floor":
                return(FloorFunction(expressions));

            case "fractionalseconds":
                return(FractionalSecondsFunction(expressions));

            case "hour":
                name       = "Hour";
                isProperty = true;
                break;

            case "indexof":
                name = "IndexOf";
                break;

            case "length":
                name       = "Length";
                isProperty = true;
                break;

            case "minute":
                name       = "Minute";
                isProperty = true;
                break;

            case "month":
                name       = "Month";
                isProperty = true;
                break;

            case "round":
                return(RoundFunction(expressions));

            case "second":
                name       = "Second";
                isProperty = true;
                break;

            case "startswith":
                name = "StartsWith";
                break;

            case "substring":
                name = "Substring";
                break;

            case "tolower":
                name = "ToLower";
                break;

            case "toupper":
                name = "ToUpper";
                break;

            case "trim":
                name = "Trim";
                break;

            case "year":
                name       = "Year";
                isProperty = true;
                break;

            default:
                throw new NotImplementedException(nodeIn.Name);
            }

            MethodInfo   methodInfo;
            PropertyInfo propertyInfo;

            switch (expressions.Count)
            {
            case 1:
                if (isProperty)
                {
                    propertyInfo = expressions[0].Type.GetProperty(name);
                    return(Expression.Property(expressions[0], propertyInfo));
                }
                else
                {
                    methodInfo = expressions[0].Type.GetMethod(name, Type.EmptyTypes);
                    return(Expression.Call(expressions[0], methodInfo));
                }

            case 2:
                methodInfo = expressions[0].Type.GetMethod(name, new Type[] { expressions[1].Type });
                return(Expression.Call(expressions[0], methodInfo, expressions[1]));

            case 3:
                methodInfo = expressions[0].Type.GetMethod(name, new Type[] { expressions[1].Type, expressions[2].Type });
                return(Expression.Call(expressions[0], methodInfo, expressions[1], expressions[2]));

            default:
                throw new NotImplementedException(name);
            }
        }