コード例 #1
0
        internal OeQueryContext(IEdmModel edmModel, ODataUri odataUri,
                                IEdmEntitySet entitySet, IReadOnlyList <OeParseNavigationSegment> parseNavigationSegments,
                                bool isCountSegment, int pageSize, bool navigationNextLink, bool isDatabaseNullHighestValue,
                                OeMetadataLevel metadataLevel, Db.OeEntitySetAdapter entitySetAdapter)
        {
            EntitySetAdapter           = entitySetAdapter;
            EdmModel                   = edmModel;
            ODataUri                   = odataUri;
            EntitySet                  = entitySet;
            ParseNavigationSegments    = parseNavigationSegments;
            IsCountSegment             = isCountSegment;
            PageSize                   = pageSize;
            NavigationNextLink         = navigationNextLink;
            IsDatabaseNullHighestValue = isDatabaseNullHighestValue;
            MetadataLevel              = metadataLevel;

            var visitor = new OeQueryNodeVisitor(edmModel, Expression.Parameter(entitySetAdapter.EntityType));

            JoinBuilder = new Translators.OeJoinBuilder(visitor);

            if (pageSize > 0 || (odataUri.OrderBy != null && odataUri.Skip != null && odataUri.Top != null))
            {
                SkipTokenNameValues = OeSkipTokenParser.CreateNameValues(edmModel, odataUri.OrderBy, odataUri.SkipToken);
            }
        }
コード例 #2
0
        public OeExpressionBuilder(IEdmModel model, Type entityType)
        {
            _model      = model;
            _entityType = entityType;

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(_entityType));
        }
コード例 #3
0
 public OeSelectTranslator(OeQueryNodeVisitor visitor, ODataPath path)
 {
     _visitor         = visitor;
     _path            = path;
     _model           = visitor.EdmModel;
     _selectItemInfos = new List <SelectItemInfo>();
 }
コード例 #4
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);
        }
コード例 #5
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);
        }
コード例 #6
0
        private static BinaryExpression CreateBinaryExpression(OeQueryNodeVisitor visitor, bool isDatabaseNullHighestValue, ref OrderProperty orderProperty)
        {
            MemberExpression propertyExpression = orderProperty.PropertyExpression;

            ConstantExpression parameterExpression = orderProperty.ParmeterExpression;

            if (parameterExpression == null)
            {
                parameterExpression = Expression.Constant(orderProperty.Value, propertyExpression.Type);
                orderProperty.ParmeterExpression = parameterExpression;
                visitor.AddSkipTokenConstant(parameterExpression, OeSkipTokenParser.GetPropertyName(propertyExpression));
            }

            ExpressionType   binaryType = orderProperty.Direction == OrderByDirection.Ascending ? ExpressionType.GreaterThan : ExpressionType.LessThan;
            BinaryExpression compare;

            if (propertyExpression.Type == typeof(String))
            {
                Func <String, String, int> compareToFunc = String.Compare;
                MethodCallExpression       compareToCall = Expression.Call(null, compareToFunc.GetMethodInfo(), propertyExpression, parameterExpression);
                compare = Expression.MakeBinary(binaryType, compareToCall, OeConstantToVariableVisitor.ZeroStringCompareConstantExpression);
            }
            else
            {
                compare = Expression.MakeBinary(binaryType, propertyExpression, parameterExpression);
            }

            if (orderProperty.PropertyNode.TypeReference.IsNullable)
            {
                BinaryExpression isNull;
                UnaryExpression  typedNull = Expression.Convert(OeConstantToVariableVisitor.NullConstantExpression, parameterExpression.Type);

                OrderByDirection direction = orderProperty.Direction;
                if (isDatabaseNullHighestValue)
                {
                    direction = orderProperty.Direction == OrderByDirection.Ascending ? OrderByDirection.Descending : OrderByDirection.Ascending;
                }

                if (direction == OrderByDirection.Ascending)
                {
                    BinaryExpression isNullParameter   = Expression.Equal(parameterExpression, typedNull);
                    BinaryExpression isNotNullProperty = Expression.NotEqual(propertyExpression, OeConstantToVariableVisitor.NullConstantExpression);
                    isNull = Expression.AndAlso(isNullParameter, isNotNullProperty);
                }
                else
                {
                    BinaryExpression isNotNullParameter = Expression.NotEqual(parameterExpression, typedNull);
                    BinaryExpression isNullProperty     = Expression.Equal(propertyExpression, OeConstantToVariableVisitor.NullConstantExpression);
                    isNull = Expression.AndAlso(isNotNullParameter, isNullProperty);
                }
                compare = Expression.OrElse(compare, isNull);
            }

            return(compare);
        }
コード例 #7
0
 public SelectItemTranslator(OeQueryNodeVisitor visitor, ODataPath path, OeMetadataLevel metadataLevel, bool navigationNextLink,
                             ParameterExpression parameter, Expression source)
 {
     _visitor            = visitor;
     _path               = path;
     _metadataLevel      = metadataLevel;
     _navigationNextLink = navigationNextLink;
     _parameter          = parameter;
     _source             = source;
     _model              = visitor.EdmModel;
 }
コード例 #8
0
        public OeQueryContext(IEdmModel edmModel, ODataUri odataUri)
        {
            EdmModel = edmModel;
            ODataUri = odataUri;

            ParseNavigationSegments = OeParseNavigationSegment.GetNavigationSegments(odataUri.Path);
            EntitySetAdapter        = edmModel.GetEntitySetAdapter((odataUri.Path.FirstSegment as EntitySetSegment).EntitySet);
            var visitor = new OeQueryNodeVisitor(Expression.Parameter(EntitySetAdapter.EntityType));

            JoinBuilder   = new Translators.OeJoinBuilder(visitor);
            MetadataLevel = OeMetadataLevel.Minimal;
        }
コード例 #9
0
        private Expression Lambda(CollectionNavigationNode sourceNode, SingleValueNode body, String methodName)
        {
            Expression   source = TranslateNode(sourceNode);
            PropertyInfo sourceNavigationProperty = Parameter.Type.GetProperty(sourceNode.NavigationProperty.Name);
            Type         targetType = OeExpressionHelper.GetCollectionItemType(sourceNavigationProperty.PropertyType);

            ParameterExpression parameter     = Expression.Parameter(targetType);
            Expression          bodyExression = new OeQueryNodeVisitor(this, parameter).TranslateNode(body);
            LambdaExpression    lambda        = Expression.Lambda(bodyExression, parameter);

            return(Expression.Call(typeof(Enumerable), methodName, new Type[] { targetType }, source, lambda));
        }
コード例 #10
0
        public OeQueryContext(IEdmModel edmModel, ODataUri odataUri, Db.OeEntitySetAdapter entitySetAdapter)
        {
            EdmModel         = edmModel;
            ODataUri         = odataUri;
            EntitySetAdapter = entitySetAdapter;

            var visitor = new OeQueryNodeVisitor(Expression.Parameter(entitySetAdapter.EntityType));

            _joinBuilder            = new Translators.OeJoinBuilder(visitor);
            MetadataLevel           = OeMetadataLevel.Minimal;
            ParseNavigationSegments = Array.Empty <OeParseNavigationSegment>();
            SkipTokenNameValues     = Array.Empty <OeSkipTokenNameValue>();
        }
コード例 #11
0
            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));
            }
コード例 #12
0
        public Expression ApplySelect(Expression source, SelectExpandClause selectClause, ODataPath path, OeMetadataLevel metadatLevel)
        {
            if (selectClause == null)
            {
                return(source);
            }

            var        selectTranslator = new OeSelectTranslator(_visitor, path);
            Expression selectExpression = selectTranslator.Build(source, selectClause, metadatLevel);

            _entryFactory = selectTranslator.CreateEntryFactory;

            Type selectItemType = OeExpressionHelper.GetCollectionItemType(selectExpression.Type);

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(selectItemType), _visitor.Constans);

            return(selectExpression);
        }
コード例 #13
0
        public Expression ApplyAggregation(Expression source, ApplyClause applyClause)
        {
            if (applyClause == null)
            {
                return(source);
            }

            var        aggTranslator = new OeAggregationTranslator(_visitor);
            Expression aggExpression = aggTranslator.Build(source, applyClause);

            _entryFactory = aggTranslator.CreateEntryFactory;

            Type aggItemType = OeExpressionHelper.GetCollectionItemType(aggExpression.Type);

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(aggItemType), _visitor.Constans);
            _visitor.TuplePropertyMapper = aggTranslator.TuplePropertyMapper;

            return(aggExpression);
        }
コード例 #14
0
        private OePropertyAccessor[] GetSkipTokenAccessors(IEdmModel edmModel, OrderByClause?orderByClause)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            Type clrEntityType            = edmModel.GetClrType(EntitySet);
            var  visitor = new OeQueryNodeVisitor(Expression.Parameter(clrEntityType));

            var skipTokenAccessors = new List <OePropertyAccessor>();

            while (orderByClause != null)
            {
                var propertyNode       = (SingleValuePropertyAccessNode)orderByClause.Expression;
                var propertyExpression = (MemberExpression)visitor.Visit(propertyNode);
                propertyExpression = OeExpressionHelper.ReplaceParameter(propertyExpression, parameter);
                skipTokenAccessors.Add(OePropertyAccessor.CreatePropertyAccessor(propertyNode.Property, propertyExpression, parameter, true));

                orderByClause = orderByClause.ThenBy;
            }

            return(skipTokenAccessors.ToArray());
        }
コード例 #15
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));
        }
コード例 #16
0
        public Expression ApplySelect(Expression source, OeQueryContext queryContext)
        {
            if (queryContext.ODataUri.SelectAndExpand == null && (queryContext.ODataUri.OrderBy == null || queryContext.PageSize == 0))
            {
                return(source);
            }

            var        selectTranslator = new OeSelectTranslator(_visitor, queryContext.ODataUri.Path);
            Expression selectExpression = selectTranslator.Build(source, queryContext);

            if (selectExpression == null)
            {
                return(source);
            }

            _entryFactory = selectTranslator.CreateEntryFactory;

            Type selectItemType = OeExpressionHelper.GetCollectionItemType(selectExpression.Type);

            _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(selectItemType), _visitor.Constans);

            return(selectExpression);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
 public OeExpressionBuilder(Translators.OeJoinBuilder joinBuilder, OeQueryNodeVisitor visitor)
 {
     _joinBuilder = joinBuilder;
     Visitor      = visitor;
 }
コード例 #19
0
 public OeOrderByTranslator(OeQueryNodeVisitor visitor)
 {
     _visitor = visitor;
 }
コード例 #20
0
 public OrderByExpressionBuider(OeQueryNodeVisitor visitor, Func <OrderByDirection, Type, Type, MethodInfo> getMethodInfo, bool isInsertedOrderByMethod)
 {
     _visitor                 = visitor;
     _getMethodInfo           = getMethodInfo;
     _isInsertedOrderByMethod = isInsertedOrderByMethod;
 }
コード例 #21
0
 public OeSkipTokenTranslator(OeQueryNodeVisitor visitor, bool isDatabaseNullHighestValue)
 {
     _visitor = visitor;
     _isDatabaseNullHighestValue = isDatabaseNullHighestValue;
 }
コード例 #22
0
 public OeQueryNodeVisitor(OeQueryNodeVisitor parentVisitor, ParameterExpression parameter)
     : this(parameter)
 {
     _parentVisitor = parentVisitor;
 }
コード例 #23
0
 private static BinaryExpression CreateBinaryExpression(OeQueryNodeVisitor visitor, bool isDatabaseNullHighestValue, in OrderProperty orderProperty)
コード例 #24
0
 public OeAggregationTranslator(OeQueryNodeVisitor visitor)
 {
     _visitor       = visitor;
     _aggProperties = new List <AggProperty>();
 }
コード例 #25
0
 public OeQueryNodeVisitor(OeQueryNodeVisitor parentVisitor, ParameterExpression it)
     : this(parentVisitor.EdmModel, it)
 {
     _parentVisitor = parentVisitor;
 }
コード例 #26
0
        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);
            }
        }
コード例 #27
0
 public OeSkipTokenTranslator(OeQueryNodeVisitor visitor, OeSkipTokenParser skipTokenParser)
 {
     _skipTokenParser = skipTokenParser;
     _visitor         = visitor;
 }