public static Db.OeAsyncEnumerator ApplyBoundFunction(OeQueryContext queryContext) { if (queryContext.ODataUri.Path.LastSegment is OperationSegment operationSegment) { var edmFunction = (IEdmFunction)operationSegment.Operations.First(); MethodInfo methodInfo = queryContext.EdmModel.GetMethodInfo(edmFunction); IReadOnlyList <KeyValuePair <String, Object> > parameterList = OeOperationHelper.GetParameters( queryContext.EdmModel, operationSegment, queryContext.ODataUri.ParameterAliasNodes); Db.OeBoundFunctionParameter boundFunctionParameter = OeOperationHelper.CreateBoundFunctionParameter(queryContext); var parameters = new Object[parameterList.Count + 1]; parameters[0] = boundFunctionParameter; for (int i = 1; i < parameters.Length; i++) { parameters[i] = parameterList[i - 1].Value; } Object result = methodInfo.Invoke(null, parameters); queryContext.EntryFactory = boundFunctionParameter.CreateEntryFactory(); if (result is IEnumerable enumerable) { return(new Db.OeAsyncEnumeratorAdapter(enumerable, CancellationToken.None)); } return(new Db.OeScalarAsyncEnumeratorAdapter(Task.FromResult(result), CancellationToken.None)); } throw new InvalidOperationException("Path last segment not OperationSegment"); }
public static Db.OeBoundFunctionParameter CreateBoundFunctionParameter(OeQueryContext queryContext) { var expressionBuilder = new OeExpressionBuilder(queryContext.JoinBuilder); 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 = new OeExpressionBuilder(queryContext.JoinBuilder); Type targetEntityType = queryContext.EdmModel.GetClrType(targetEntitySet.EntityType()); Expression target = OeEnumerableStub.CreateEnumerableStubExpression(targetEntityType, targetEntitySet); target = expressionBuilder.ApplySelect(target, queryContext); var sourceQueryExpression = new OeQueryExpression(queryContext.EdmModel, sourceEntitySet, source); var targetQueryExpression = new OeQueryExpression(queryContext.EdmModel, targetEntitySet, target) { EntryFactory = expressionBuilder.CreateEntryFactory(targetEntitySet) }; Type boundFunctionParameterType = typeof(Db.OeBoundFunctionParameter <,>).MakeGenericType(new[] { sourceEntityType, targetEntityType }); ConstructorInfo ctor = boundFunctionParameterType.GetConstructor(new[] { typeof(OeQueryExpression), typeof(OeQueryExpression) }); return((Db.OeBoundFunctionParameter)ctor.Invoke(new Object[] { sourceQueryExpression, targetQueryExpression })); }
public Db.OeAsyncEnumerator GetAsyncEnumerator(ODataUri odataUri, Stream requestStream, OeRequestHeaders headers, Object dataContext, out bool isScalar) { isScalar = true; var importSegment = (OperationImportSegment)odataUri.Path.LastSegment; IReadOnlyList<KeyValuePair<String, Object>> parameters = OeOperationHelper.GetParameters(_edmModel, importSegment, odataUri.ParameterAliasNodes, requestStream, headers.ContentType); IEdmOperationImport operationImport = importSegment.OperationImports.Single(); IEdmEntitySet entitySet = OeOperationHelper.GetEntitySet(operationImport); if (entitySet == null) { if (operationImport.Operation.ReturnType == null) return _dataAdapter.OperationAdapter.ExecuteProcedureNonQuery(dataContext, operationImport.Name, parameters); Type returnType = _edmModel.GetClrType(operationImport.Operation.ReturnType.Definition); if (operationImport.Operation.ReturnType.IsCollection()) { isScalar = false; returnType = typeof(IEnumerable<>).MakeGenericType(returnType); } if (_edmModel.IsDbFunction(operationImport.Operation)) return _dataAdapter.OperationAdapter.ExecuteFunctionPrimitive(dataContext, operationImport.Name, parameters, returnType); else return _dataAdapter.OperationAdapter.ExecuteProcedurePrimitive(dataContext, operationImport.Name, parameters, returnType); } isScalar = false; Db.OeEntitySetAdapter entitySetAdapter = _dataAdapter.EntitySetAdapters.Find(entitySet); if (_edmModel.IsDbFunction(operationImport.Operation)) return _dataAdapter.OperationAdapter.ExecuteFunctionReader(dataContext, operationImport.Name, parameters, entitySetAdapter); else return _dataAdapter.OperationAdapter.ExecuteProcedureReader(dataContext, operationImport.Name, parameters, entitySetAdapter); }
public async Task ExecuteAsync(ODataUri odataUri, Stream?requestStream, OeRequestHeaders headers, Stream responseStream, CancellationToken cancellationToken) { Object?dataContext = null; try { dataContext = _dataAdapter.CreateDataContext(); IAsyncEnumerator <Object>?asyncEnumerator = null; try { asyncEnumerator = GetAsyncEnumerable(odataUri, requestStream, headers, dataContext, cancellationToken, out bool isScalar).GetAsyncEnumerator(cancellationToken); if (isScalar) { if (await asyncEnumerator.MoveNextAsync().ConfigureAwait(false) && asyncEnumerator.Current != null) { headers.ResponseContentType = OeRequestHeaders.TextDefault.ContentType; byte[] buffer = System.Text.Encoding.UTF8.GetBytes(asyncEnumerator.Current.ToString()); await responseStream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false); } else { headers.ResponseContentType = null; } } else { var importSegment = (OperationImportSegment)odataUri.Path.FirstSegment; IEdmEntitySet?entitySet = OeOperationHelper.GetEntitySet(importSegment.OperationImports.Single()); if (entitySet == null) { await WriteCollectionAsync(_edmModel, odataUri, asyncEnumerator, responseStream).ConfigureAwait(false); } else { OeQueryContext queryContext = CreateQueryContext(odataUri, entitySet, headers.MetadataLevel); await Writers.OeGetWriter.SerializeAsync(queryContext, asyncEnumerator, headers.ContentType, responseStream, _serviceProvider, cancellationToken).ConfigureAwait(false); } } } finally { if (asyncEnumerator != null) { await asyncEnumerator.DisposeAsync().ConfigureAwait(false); } } } finally { if (dataContext != null) { _dataAdapter.CloseDataContext(dataContext); } } }
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), }; }
public async Task ExecuteAsync(ODataUri odataUri, OeRequestHeaders headers, Stream stream, CancellationToken cancellationToken) { if (_modelBoundProvider != null) { _modelBoundProvider.Validate(_edmModel, odataUri); } var queryContext = new OeQueryContext(_edmModel, odataUri) { MetadataLevel = headers.MetadataLevel }; if (queryContext.ODataUri.Path.LastSegment is OperationSegment) { using (IAsyncEnumerator <Object> asyncEnumerator = OeOperationHelper.ApplyBoundFunction(queryContext).GetEnumerator()) await Writers.OeGetWriter.SerializeAsync(queryContext, asyncEnumerator, headers.ContentType, stream, cancellationToken).ConfigureAwait(false); return; } Object dataContext = null; Db.OeDataAdapter dataAdapter = queryContext.EdmModel.GetDataAdapter(queryContext.EdmModel.EntityContainer); try { dataContext = dataAdapter.CreateDataContext(); if (odataUri.Path.LastSegment is CountSegment) { headers.ResponseContentType = OeRequestHeaders.TextDefault.ContentType; int count = dataAdapter.ExecuteScalar <int>(dataContext, queryContext); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(count.ToString(CultureInfo.InvariantCulture)); stream.Write(buffer, 0, buffer.Length); } else { using (IAsyncEnumerator <Object> asyncEnumerator = dataAdapter.Execute(dataContext, queryContext).GetEnumerator()) await Writers.OeGetWriter.SerializeAsync(queryContext, asyncEnumerator, headers.ContentType, stream, cancellationToken).ConfigureAwait(false); } } finally { if (dataContext != null) { dataAdapter.CloseDataContext(dataContext); } } }
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); } OePropertyAccessor[] accessors = OePropertyAccessor.CreateFromType(_edmModel.GetClrType(entitySet), entitySet); Db.OeEntitySetAdapter entitySetAdapter = _dataAdapter.EntitySetAdapters.Find(entitySet); return(new OeQueryContext(_edmModel, odataUri, entitySetAdapter) { EntryFactory = new OeEntryFactory(entitySet, accessors, Array.Empty <OePropertyAccessor>()), MetadataLevel = metadataLevel }); }
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)); }