예제 #1
0
        private OeEntryFactory CreateNestedEntryFactory(Type sourceType, IEdmEntitySet entitySet, ODataNestedResourceInfo resourceInfo)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            IReadOnlyList <MemberExpression> itemExpressions = OeExpressionHelper.GetPropertyExpression(Expression.Convert(parameter, sourceType));

            List <OeEntryFactory> navigationLinks = GetNavigationLinks(itemExpressions, parameter);

            OePropertyAccessor[] accessors;
            if (_pathSelect)
            {
                var accessorsList = new List <OePropertyAccessor>(_selectItemInfos.Count);
                for (int i = 0; i < _selectItemInfos.Count; i++)
                {
                    SelectItemInfo info = _selectItemInfos[i];
                    if (info.EdmProperty is IEdmStructuralProperty)
                    {
                        accessorsList.Add(OePropertyAccessor.CreatePropertyAccessor(info.EdmProperty, itemExpressions[i], parameter));
                    }
                }
                accessors = accessorsList.ToArray();
            }
            else
            {
                accessors = OePropertyAccessor.CreateFromExpression(itemExpressions[0], parameter, entitySet);
            }

            return(OeEntryFactory.CreateEntryFactoryNested(entitySet, accessors, resourceInfo, navigationLinks));
        }
예제 #2
0
        private List <OeEntryFactory> GetNavigationLinks(IReadOnlyList <MemberExpression> itemExpressions, ParameterExpression parameter)
        {
            var navigationLinks = new List <OeEntryFactory>(_selectItemInfos.Count);

            for (int i = 0; i < _selectItemInfos.Count; i++)
            {
                SelectItemInfo itemInfo = _selectItemInfos[i];
                if (itemInfo.EdmProperty is IEdmNavigationProperty)
                {
                    MemberExpression expression = itemExpressions[_pathSelect ? i : i + 1];

                    OeEntryFactory entryFactory;
                    if (itemInfo.EntryFactory == null)
                    {
                        Type type = expression.Type;
                        if (itemInfo.ResourceInfo.IsCollection.GetValueOrDefault())
                        {
                            type = OeExpressionHelper.GetCollectionItemType(type);
                        }

                        OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(type, itemInfo.EntitySet);
                        entryFactory             = OeEntryFactory.CreateEntryFactoryChild(itemInfo.EntitySet, accessors, itemInfo.ResourceInfo);
                        entryFactory.CountOption = itemInfo.CountOption;
                    }
                    else
                    {
                        entryFactory = itemInfo.EntryFactory;
                    }
                    entryFactory.LinkAccessor = (Func <Object, Object>)Expression.Lambda(expression, parameter).Compile();

                    navigationLinks.Add(entryFactory);
                }
            }
            return(navigationLinks);
        }
예제 #3
0
 public OeQueryExpression(IEdmModel edmModel, IEdmEntitySet entitySet, Expression expression, OeEntryFactory entryFactory = null)
 {
     EdmModel     = edmModel;
     _entitySet   = entitySet;
     _expression  = new OeEnumerableToQuerableVisitor().Visit(expression);
     EntryFactory = entryFactory;
 }
예제 #4
0
        public OeEntryFactory CreateEntryFactory(Type entityType, IEdmEntitySetBase entitySet, Type sourceType)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            IReadOnlyList <MemberExpression> itemExpressions = OeExpressionHelper.GetPropertyExpression(Expression.Convert(parameter, sourceType));

            OeEntryFactory        entryFactory;
            List <OeEntryFactory> navigationLinks = GetNavigationLinks(itemExpressions, parameter);

            if (_pathSelect)
            {
                var accessors = new List <OePropertyAccessor>(_selectItemInfos.Count);
                for (int i = 0; i < _selectItemInfos.Count; i++)
                {
                    SelectItemInfo info = _selectItemInfos[i];
                    if (info.EdmProperty is IEdmStructuralProperty)
                    {
                        accessors.Add(OePropertyAccessor.CreatePropertyAccessor(info.EdmProperty, itemExpressions[i], parameter));
                    }
                }
                entryFactory = OeEntryFactory.CreateEntryFactoryParent(entitySet, accessors.ToArray(), navigationLinks);
            }
            else
            {
                OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(entityType, entitySet);
                entryFactory = OeEntryFactory.CreateEntryFactoryParent(entitySet, accessors, navigationLinks);
                entryFactory.LinkAccessor = (Func <Object, Object>)Expression.Lambda(itemExpressions[0], parameter).Compile();
            }
            return(entryFactory);
        }
예제 #5
0
        public OeEntryFactory GetEntryFactoryFromTuple(IEdmModel edmModel, OrderByClause orderByClause)
        {
            if (_entryFactoryFromTuple == null)
            {
                OePropertyAccessor[] skipTokenAccessors;
                if (IsTuple)
                {
                    if (SkipTokenAccessors.Length > 0)
                    {
                        skipTokenAccessors = GetSkipTokenAccessors(edmModel, orderByClause);
                    }
                    else
                    {
                        skipTokenAccessors = Array.Empty <OePropertyAccessor>();
                    }
                }
                else
                {
                    skipTokenAccessors = SkipTokenAccessors;
                }

                _entryFactoryFromTuple = CreateEntryFactoryFromTuple(edmModel, null, skipTokenAccessors);
            }
            return(_entryFactoryFromTuple);
        }
예제 #6
0
        public static Db.OeBoundFunctionParameter CreateBoundFunctionParameter(OeQueryContext queryContext)
        {
            var expressionBuilder = queryContext.CreateExpressionBuilder();

            Type          sourceEntityType = queryContext.EntitySetAdapter.EntityType;
            IEdmEntitySet sourceEntitySet  = OeEdmClrHelper.GetEntitySet(queryContext.EdmModel, queryContext.EntitySetAdapter.EntitySetName);
            Expression    source           = OeEnumerableStub.CreateEnumerableStubExpression(sourceEntityType, sourceEntitySet);

            source = expressionBuilder.ApplyNavigation(source, queryContext.ParseNavigationSegments);

            IEdmEntitySet targetEntitySet = OeOperationHelper.GetEntitySet(queryContext.ODataUri.Path);

            if (sourceEntitySet != targetEntitySet)
            {
                queryContext.ODataUri.Path = new ODataPath(new EntitySetSegment(targetEntitySet));
            }

            expressionBuilder = queryContext.CreateExpressionBuilder();
            Type       targetEntityType = queryContext.EdmModel.GetClrType(targetEntitySet.EntityType());
            Expression target           = OeEnumerableStub.CreateEnumerableStubExpression(targetEntityType, targetEntitySet);

            target = expressionBuilder.ApplySelect(target, queryContext);

            OeEntryFactory targetEntryFactory    = expressionBuilder.CreateEntryFactory(targetEntitySet, Array.Empty <OePropertyAccessor>());
            var            sourceQueryExpression = new OeQueryExpression(queryContext.EdmModel, sourceEntitySet, source);
            var            targetQueryExpression = new OeQueryExpression(queryContext.EdmModel, targetEntitySet, target, targetEntryFactory);

            Type            boundFunctionParameterType = typeof(Db.OeBoundFunctionParameter <,>).MakeGenericType(new[] { sourceEntityType, targetEntityType });
            ConstructorInfo ctor = boundFunctionParameterType.GetConstructors()[0];

            return((Db.OeBoundFunctionParameter)ctor.Invoke(new Object[] { sourceQueryExpression, targetQueryExpression }));
        }
예제 #7
0
        private OeEntryFactory CreateEntryFactoryFromTuple(IEdmModel edmModel, OeEntryFactory?parentEntryFactory, OePropertyAccessor[] skipTokenAccessors)
        {
            OePropertyAccessor[] accessors = _allAccessors;
            if (IsTuple)
            {
                OePropertyAccessor[] propertyAccessors = OePropertyAccessor.CreateFromType(edmModel.GetClrType(EntitySet), EntitySet);
                accessors = new OePropertyAccessor[_allAccessors.Length];
                for (int i = 0; i < accessors.Length; i++)
                {
                    OePropertyAccessor accessor = Array.Find(propertyAccessors, pa => pa.EdmProperty == _allAccessors[i].EdmProperty);
                    if (Array.IndexOf(Accessors, _allAccessors[i]) == -1)
                    {
                        var convertExpression   = (UnaryExpression)accessor.PropertyExpression.Expression;
                        var parameterExpression = (ParameterExpression)convertExpression.Operand;
                        accessor = OePropertyAccessor.CreatePropertyAccessor(accessor.EdmProperty, accessor.PropertyExpression, parameterExpression, true);
                    }
                    accessors[i] = accessor;
                }
            }

            var navigationLinks = new OeEntryFactory[NavigationLinks.Count];

            for (int i = 0; i < NavigationLinks.Count; i++)
            {
                navigationLinks[i] = NavigationLinks[i].CreateEntryFactoryFromTuple(edmModel, this, Array.Empty <OePropertyAccessor>());
            }

            OeEntryFactoryOptions options;

            if (parentEntryFactory == null)
            {
                options = new OeEntryFactoryOptions()
                {
                    Accessors          = accessors,
                    EntitySet          = EntitySet,
                    NavigationLinks    = navigationLinks,
                    SkipTokenAccessors = skipTokenAccessors,
                };
                return(new OeEntryFactory(ref options));
            }

            ParameterExpression parameter      = Expression.Parameter(typeof(Object));
            UnaryExpression     typedParameter = Expression.Convert(parameter, edmModel.GetClrType(parentEntryFactory.EntitySet));
            MemberExpression    navigationPropertyExpression = Expression.Property(typedParameter, EdmNavigationProperty.Name);
            LambdaExpression    linkAccessor = Expression.Lambda(navigationPropertyExpression, parameter);

            options = new OeEntryFactoryOptions()
            {
                Accessors             = accessors,
                EdmNavigationProperty = EdmNavigationProperty,
                EntitySet             = EntitySet,
                LinkAccessor          = linkAccessor,
                NavigationLinks       = navigationLinks,
                NavigationSelectItem  = NavigationSelectItem,
                SkipTokenAccessors    = skipTokenAccessors,
            };
            return(new OeEntryFactory(ref options));
        }
예제 #8
0
        public OeEntryFactory CreateEntryFactory(IEdmEntitySet entitySet)
        {
            if (_entryFactoryFactory != null)
            {
                return(_entryFactoryFactory(entitySet, ParameterType));
            }

            OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(ParameterType, entitySet);
            return(OeEntryFactory.CreateEntryFactory(entitySet, accessors));
        }
예제 #9
0
 public OeEntryFactory CreateEntryFactory(Type entityType, IEdmEntitySet entitySet, Type sourceType)
 {
     OePropertyAccessor[] accessors;
     if (_aggProperties.Count == 0)
     {
         accessors = OePropertyAccessor.CreateFromType(entityType, entitySet);
     }
     else
     {
         accessors = OePropertyAccessor.CreateFromTuple(sourceType, _aggProperties, 0);
     }
     return(OeEntryFactory.CreateEntryFactory(entitySet, accessors));
 }
예제 #10
0
 public OeEntryFactory CreateEntryFactory(Type entityType, IEdmEntitySet entitySet, Type sourceType)
 {
     OePropertyAccessor[] accessors;
     if (_aggProperties.Count == 0)
     {
         accessors = OePropertyAccessor.CreateFromType(entityType, entitySet);
     }
     else
     {
         int groupIndex = _aggProperties.FindIndex(a => a.IsGroup);
         accessors = OePropertyAccessor.CreateFromTuple(sourceType, _aggProperties, groupIndex);
     }
     return(OeEntryFactory.CreateEntryFactory(entitySet, accessors));
 }
예제 #11
0
        public Expression ApplySelect(Expression source, OeQueryContext queryContext)
        {
            if (queryContext.ODataUri.Path.LastSegment is CountSegment)
            {
                return(source);
            }

            var selectTranslator = new Translators.OeSelectTranslator(_joinBuilder, queryContext.ODataUri.Path, queryContext.MetadataLevel);

            source        = selectTranslator.Build(source, queryContext);
            _entryFactory = selectTranslator.EntryFactory;

            ChangeParameterType(source);
            return(source);
        }
예제 #12
0
        public OeQueryContext CreateQueryContext(ODataUri odataUri, OeMetadataLevel metadataLevel)
        {
            var importSegment = (OperationImportSegment)odataUri.Path.FirstSegment;
            IEdmEntitySet entitySet = OeOperationHelper.GetEntitySet(importSegment.OperationImports.Single());
            if (entitySet == null)
                return null;

            Type clrType = _edmModel.GetClrType(entitySet.EntityType());
            OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(clrType, entitySet);

            Db.OeEntitySetAdapter entitySetAdapter = _dataAdapter.EntitySetAdapters.Find(entitySet);
            return new OeQueryContext(_edmModel, odataUri, null, false, 0, false, metadataLevel, entitySetAdapter)
            {
                EntryFactory = OeEntryFactory.CreateEntryFactory(entitySet, accessors),
            };
        }
예제 #13
0
        public Expression ApplyAggregation(Expression source, ApplyClause applyClause)
        {
            if (applyClause == null)
            {
                return(source);
            }

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

            _entryFactory = aggTranslator.EntryFactory;

            ChangeParameterType(aggExpression);
            Visitor.TuplePropertyByAliasName = aggTranslator.GetTuplePropertyByAliasName;

            return(aggExpression);
        }
예제 #14
0
        private OeEntryFactory CreateEntryFactory(OeExpressionBuilder expressionBuilder)
        {
            IEdmEntitySetBase entitySet = EntitySet;

            if (expressionBuilder.EntityType != EntitySetAdapter.EntityType)
            {
                String                    typeName             = expressionBuilder.EntityType.FullName;
                Db.OeDataAdapter          dataAdapter          = EntitySetAdapter.DataAdapter;
                Db.OeEntitySetMetaAdapter entitySetMetaAdapter = dataAdapter.EntitySetMetaAdapters.FindByTypeName(typeName);
                if (entitySetMetaAdapter != null)
                {
                    entitySet = EdmModel.FindDeclaredEntitySet(entitySetMetaAdapter.EntitySetName);
                }
            }

            OeEntryFactory entryFactory = expressionBuilder.CreateEntryFactory(entitySet);

            entryFactory.CountOption = ODataUri.QueryCount;
            return(entryFactory);
        }
예제 #15
0
        private OeEntryFactory CreateEntryFactory(OeExpressionBuilder expressionBuilder)
        {
            IEdmEntitySet entitySet;

            if (ODataUri.Path.LastSegment is OperationSegment)
            {
                entitySet = OeOperationHelper.GetEntitySet(ODataUri.Path);
                Type clrEntityType             = EdmModel.GetClrType(entitySet.EntityType());
                OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(clrEntityType, entitySet);
                return(OeEntryFactory.CreateEntryFactory(entitySet, accessors));
            }

            entitySet = OeParseNavigationSegment.GetEntitySet(ParseNavigationSegments);
            if (entitySet == null)
            {
                entitySet = OeEdmClrHelper.GetEntitySet(EdmModel, EntitySetAdapter.EntitySetName);
            }

            return(expressionBuilder.CreateEntryFactory(entitySet));
        }
예제 #16
0
        private OeEntryFactory CreateEntryFactoryFromTuple(OeEntryFactory parentEntryFactory)
        {
            OePropertyAccessor[] accessors = _allAccessors;
            if (IsTuple)
            {
                accessors = new OePropertyAccessor[_allAccessors.Length];
                OePropertyAccessor[] propertyAccessors = OePropertyAccessor.CreateFromType(ClrEntityType, EntitySet);
                for (int i = 0; i < accessors.Length; i++)
                {
                    OePropertyAccessor accessor = Array.Find(propertyAccessors, pa => pa.EdmProperty == _allAccessors[i].EdmProperty);
                    if (Array.IndexOf(Accessors, _allAccessors[i]) == -1)
                    {
                        var convertExpression   = (UnaryExpression)accessor.PropertyExpression.Expression;
                        var parameterExpression = (ParameterExpression)convertExpression.Operand;
                        accessor = OePropertyAccessor.CreatePropertyAccessor(accessor.EdmProperty, accessor.PropertyExpression, parameterExpression, true);
                    }
                    accessors[i] = accessor;
                }
            }

            var navigationLinks = new OeEntryFactory[NavigationLinks.Count];

            for (int i = 0; i < NavigationLinks.Count; i++)
            {
                navigationLinks[i] = NavigationLinks[i].CreateEntryFactoryFromTuple(this);
            }

            if (parentEntryFactory == null)
            {
                return(OeEntryFactory.CreateEntryFactoryParent(ClrEntityType, EntitySet, accessors, navigationLinks, null));
            }

            ParameterExpression parameter      = Expression.Parameter(typeof(Object));
            UnaryExpression     typedParameter = Expression.Convert(parameter, parentEntryFactory.ClrEntityType);
            MemberExpression    navigationPropertyExpression = Expression.Property(typedParameter, ResourceInfo.Name);
            LambdaExpression    linkAccessor = Expression.Lambda(navigationPropertyExpression, parameter);

            return(OeEntryFactory.CreateEntryFactoryNested(ClrEntityType, EntitySet, accessors, navigationLinks, linkAccessor, ResourceInfo));
        }
예제 #17
0
        public async Task ExecuteAsync(ODataUri odataUri, Stream requestStream, OeRequestHeaders headers, Stream responseStream, CancellationToken cancellationToken)
        {
            var importSegment = (OperationImportSegment)odataUri.Path.LastSegment;

            List <KeyValuePair <String, Object> > parameters = GetParameters(importSegment, requestStream, headers.ContentType);
            Object dataContext = null;

            try
            {
                dataContext = _dataAdapter.CreateDataContext();

                var operation = (EdmOperation)importSegment.OperationImports.Single().Operation;

                String procedureName;
                if (String.IsNullOrEmpty(operation.Namespace))
                {
                    procedureName = operation.Name;
                }
                else
                {
                    procedureName = operation.Namespace + "." + operation.Name;
                }

                Type returnClrType = null;
                if (operation.ReturnType != null)
                {
                    IEdmTypeReference returnEdmTypeReference = operation.ReturnType;
                    if (returnEdmTypeReference is IEdmCollectionTypeReference)
                    {
                        returnEdmTypeReference = (returnEdmTypeReference.Definition as IEdmCollectionType).ElementType;
                    }
                    returnClrType = OeEdmClrHelper.GetClrType(_model, returnEdmTypeReference.Definition);
                }

                using (Db.OeEntityAsyncEnumerator asyncEnumerator = _dataAdapter.ExecuteProcedure(dataContext, procedureName, parameters, returnClrType))
                {
                    if (returnClrType == null)
                    {
                        if (await asyncEnumerator.MoveNextAsync() && asyncEnumerator.Current != null)
                        {
                            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(asyncEnumerator.Current.ToString());
                            responseStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                    else
                    {
                        String        entitySetName               = _dataAdapter.EntitySetMetaAdapters.FindByClrType(returnClrType).EntitySetName;
                        IEdmEntitySet entitySet                   = _model.FindDeclaredEntitySet(entitySetName);
                        Parsers.OePropertyAccessor[] accessors    = Parsers.OePropertyAccessor.CreateFromType(returnClrType, entitySet);
                        Parsers.OeEntryFactory       entryFactory = Parsers.OeEntryFactory.CreateEntryFactory(entitySet, accessors);

                        var parseUriContext = new Parsers.OeParseUriContext(_model, odataUri, entitySet, null, false)
                        {
                            EntryFactory = entryFactory,
                            Headers      = headers
                        };
                        await Writers.OeGetWriter.SerializeAsync(_baseUri, parseUriContext, asyncEnumerator, responseStream).ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                if (dataContext != null)
                {
                    _dataAdapter.CloseDataContext(dataContext);
                }
            }

            await Task.CompletedTask;
        }
예제 #18
0
        protected override OeNavigationEntryFactory CreateEntryFactoryFromTuple(IEdmModel edmModel, OeEntryFactory parentEntryFactory)
        {
            OePropertyAccessor[] accessors = base.GetAccessorsFromTuple(edmModel);
            var navigationLinks            = new OeNavigationEntryFactory[NavigationLinks.Count];

            for (int i = 0; i < NavigationLinks.Count; i++)
            {
                navigationLinks[i] = NavigationLinks[i].CreateEntryFactoryFromTuple(edmModel, this);
            }

            ParameterExpression parameter      = Expression.Parameter(typeof(Object));
            UnaryExpression     typedParameter = Expression.Convert(parameter, edmModel.GetClrType(parentEntryFactory.EntitySet));
            MemberExpression    navigationPropertyExpression = Expression.Property(typedParameter, EdmNavigationProperty.Name);
            LambdaExpression    linkAccessor = Expression.Lambda(navigationPropertyExpression, parameter);

            return(new OeNavigationEntryFactory(
                       EntitySet,
                       accessors,
                       null,
                       navigationLinks,
                       linkAccessor,
                       EdmNavigationProperty,
                       NavigationSelectItem,
                       false));
        }
예제 #19
0
 protected virtual OeNavigationEntryFactory CreateEntryFactoryFromTuple(IEdmModel edmModel, OeEntryFactory parentEntryFactory)
 {
     throw new InvalidOperationException("Must be invoke for " + nameof(OeNavigationEntryFactory));
 }