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 })); }
protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Arguments.Count > 0 && node.Arguments[0] is MemberExpression navigationPropertyExpression) { Type?innerItemType = OeExpressionHelper.GetCollectionItemTypeOrNull(navigationPropertyExpression.Type); if (innerItemType != null) { IEdmModel edmModel = _edmModel.GetEdmModel(innerItemType) ?? throw new InvalidOperationException("Cannot find IEdmModel for type " + innerItemType.FullName); Db.OeDataAdapter dataAdapter = edmModel.GetDataAdapter(edmModel.EntityContainer); Db.OeEntitySetAdapter?innerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(innerItemType); if (innerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + innerItemType.Name); } IEdmEntitySet entitySet = edmModel.FindDeclaredEntitySet(innerEntitySetAdapter.EntitySetName); ConstantExpression innerSource = OeEnumerableStub.CreateEnumerableStubExpression(innerEntitySetAdapter.EntityType, entitySet); IEdmNavigationProperty navigationProperty = GetEdmNavigationProperty(dataAdapter, navigationPropertyExpression); Expression[] arguments = node.Arguments.ToArray(); arguments[0] = GetJoin(innerSource, navigationProperty); return(node.Update(node.Object !, arguments)); } } return(base.VisitMethodCall(node)); }
private MethodCallExpression?GetJoin(Expression outer, MemberExpression navigationProperty) { Type outerType = outer.Type; Type innerType = navigationProperty.Type; IEdmModel?edmModel = _edmModel.GetEdmModel(outerType); if (edmModel == null) { return(null); } Db.OeDataAdapter dataAdapter = edmModel.GetDataAdapter(edmModel.EntityContainer); Db.OeEntitySetAdapter?outerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(outerType); if (outerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + outerType.Name); } IEdmEntitySet outerEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, outerEntitySetAdapter.EntitySetName); IEdmNavigationProperty edmNavigationProperty = outerEntitySet.EntityType().NavigationProperties().Single(p => p.Name == navigationProperty.Member.Name); Db.OeEntitySetAdapter?innerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(innerType); if (innerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + innerType.Name); } IEdmEntitySet entitySet = edmModel.FindDeclaredEntitySet(innerEntitySetAdapter.EntitySetName); ConstantExpression innerSource = OeEnumerableStub.CreateEnumerableStubExpression(innerType, entitySet); return(GetJoin(outer, innerSource, edmNavigationProperty)); }
public Expression CreateExpression(out IReadOnlyDictionary <ConstantExpression, ConstantNode> constants) { Initialize(); Expression expression; var expressionBuilder = new OeExpressionBuilder(_joinBuilder); IEdmEntitySet entitySet = OeEdmClrHelper.GetEntitySet(EdmModel, EntitySetAdapter.EntitySetName); expression = OeEnumerableStub.CreateEnumerableStubExpression(EntitySetAdapter.EntityType, entitySet); expression = expressionBuilder.ApplyNavigation(expression, ParseNavigationSegments); if (ODataUri.Apply == null) { expression = expressionBuilder.ApplyFilter(expression, ODataUri.Filter); expression = expressionBuilder.ApplySelect(expression, this); } else { expression = expressionBuilder.ApplyAggregation(expression, ODataUri.Apply); expression = expressionBuilder.ApplyFilter(expression, ODataUri.Filter); expression = expressionBuilder.ApplySkipToken(expression, SkipTokenNameValues, ODataUri.OrderBy, IsDatabaseNullHighestValue); //order by aggregation expression = expressionBuilder.ApplyOrderBy(expression, ODataUri.OrderBy); expression = expressionBuilder.ApplySkip(expression, ODataUri.Skip, ODataUri.Path); expression = expressionBuilder.ApplyTake(expression, ODataUri.Top, ODataUri.Path); } if (ODataUri.Path.LastSegment is CountSegment) { expression = expressionBuilder.ApplyCount(expression, true); } else { OePropertyAccessor[] skipTokenAccessors = OeSkipTokenParser.GetAccessors(expression, ODataUri.OrderBy, _joinBuilder); EntryFactory = CreateEntryFactory(expressionBuilder, skipTokenAccessors); } constants = expressionBuilder.Constants; return(expression); }
public Expression CreateExpression(OeConstantToVariableVisitor constantToVariableVisitor) { Expression expression; var expressionBuilder = new OeExpressionBuilder(JoinBuilder); IEdmEntitySet entitySet = OeEdmClrHelper.GetEntitySet(EdmModel, EntitySetAdapter.EntitySetName); expression = OeEnumerableStub.CreateEnumerableStubExpression(EntitySetAdapter.EntityType, entitySet); expression = expressionBuilder.ApplyNavigation(expression, ParseNavigationSegments); expression = expressionBuilder.ApplyFilter(expression, ODataUri.Filter); if (ODataUri.Apply == null) { expression = expressionBuilder.ApplySelect(expression, this); } else { expression = expressionBuilder.ApplySkipToken(expression, SkipTokenNameValues, ODataUri.OrderBy, IsDatabaseNullHighestValue); expression = expressionBuilder.ApplyAggregation(expression, ODataUri.Apply); expression = expressionBuilder.ApplyOrderBy(expression, ODataUri.OrderBy); expression = expressionBuilder.ApplySkip(expression, ODataUri.Skip, ODataUri.Path); expression = expressionBuilder.ApplyTake(expression, ODataUri.Top, ODataUri.Path); } expression = expressionBuilder.ApplyCount(expression, IsCountSegment); if (!IsCountSegment) { EntryFactory = CreateEntryFactory(expressionBuilder); } if (SkipTokenNameValues != null) { SkipTokenAccessors = OeSkipTokenParser.GetAccessors(expression, ODataUri.OrderBy, JoinBuilder); } return(constantToVariableVisitor.Translate(expression, expressionBuilder.Constants)); }