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.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); } sourceItemType = selectType; } Visitor.ChangeParameterType(Expression.Parameter(sourceItemType)); return(source); }
private static MethodCallExpression AggCallExpression(AggregationMethod aggMethod, ParameterExpression sourceParameter, LambdaExpression lambda) { String methodName; switch (aggMethod) { case AggregationMethod.Average: methodName = nameof(Enumerable.Average); break; case AggregationMethod.CountDistinct: return(CountDistinctExpression(sourceParameter, lambda)); case AggregationMethod.Max: methodName = nameof(Enumerable.Max); break; case AggregationMethod.Min: methodName = nameof(Enumerable.Min); break; case AggregationMethod.Sum: methodName = nameof(Enumerable.Sum); break; default: throw new NotSupportedException(); } MethodInfo closeMethod; MethodInfo openMethod = OeMethodInfoHelper.GetAggMethodInfo(methodName, lambda.ReturnType); if (openMethod == null) { Func <IEnumerable <Object>, Func <Object, Object>, Object> aggFunc; switch (aggMethod) { case AggregationMethod.Max: aggFunc = Enumerable.Max <Object, Object>; break; case AggregationMethod.Min: aggFunc = Enumerable.Min <Object, Object>; break; default: throw new InvalidOperationException($"Enumerable.{methodName} not found");; } openMethod = aggFunc.GetMethodInfo().GetGenericMethodDefinition(); closeMethod = openMethod.MakeGenericMethod(lambda.Parameters[0].Type, lambda.ReturnType); } else { closeMethod = openMethod.MakeGenericMethod(lambda.Parameters[0].Type); } return(Expression.Call(closeMethod, sourceParameter, lambda)); }
private MethodCallExpression ApplyGroupBy(Expression source, GroupByTransformationNode transformation) { Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type); ParameterExpression sourceParameter = Expression.Parameter(sourceType); var visitor = CreateVisitor(sourceParameter); var expressions = new List <Expression>(); foreach (GroupByPropertyNode node in transformation.GroupingProperties) { if (node.ChildTransformations != null && node.ChildTransformations.Count > 0) { if (node.ChildTransformations.Count > 1) { throw new NotSupportedException(); } GroupByPropertyNode childNode = node.ChildTransformations[0]; String propertyName = node.Name + "_" + childNode.Name; Expression e = visitor.TranslateNode(childNode.Expression); expressions.Add(e); _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, e.Type, propertyName, true)); } else { Expression e = visitor.TranslateNode(node.Expression); expressions.Add(e); _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, e.Type, node.Name, true)); } } NewExpression newExpression = OeExpressionHelper.CreateTupleExpression(expressions); LambdaExpression lambda = Expression.Lambda(newExpression, sourceParameter); MethodInfo groupByMethodInfo = OeMethodInfoHelper.GetGroupByMethodInfo(sourceType, newExpression.Type); MethodCallExpression groupByCall = Expression.Call(groupByMethodInfo, source, lambda); var aggTransformation = (AggregateTransformationNode)transformation.ChildTransformations; if (aggTransformation == null) { expressions.Clear(); sourceType = OeExpressionHelper.GetCollectionItemType(groupByCall.Type); sourceParameter = Expression.Parameter(sourceType); expressions.Add(Expression.Property(sourceParameter, nameof(IGrouping <Object, Object> .Key))); newExpression = OeExpressionHelper.CreateTupleExpression(expressions); MethodInfo selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceType, newExpression.Type); lambda = Expression.Lambda(newExpression, sourceParameter); return(Expression.Call(selectMethodInfo, groupByCall, lambda)); } return(ApplyAggregate(groupByCall, aggTransformation)); }
public override Expression Translate(ExpandedNavigationSelectItem item) { var segment = (NavigationPropertySegment)item.PathToNavigationProperty.LastSegment; Expression expression = Translate(segment); Type navigationItemType = expression.Type; Type itemType = OeExpressionHelper.GetCollectionItemType(navigationItemType); if (itemType != null) { var expressionBuilder = new OeExpressionBuilder(_model, itemType); expression = expressionBuilder.ApplyFilter(expression, item.FilterOption); expression = expressionBuilder.ApplyOrderBy(expression, item.OrderByOption); var path = new ODataPath(_path.Union(item.PathToNavigationProperty)); expression = expressionBuilder.ApplySkip(expression, item.SkipOption, path); expression = expressionBuilder.ApplyTake(expression, item.TopOption, path); foreach (KeyValuePair <ConstantExpression, ConstantNode> constant in expressionBuilder.Constants) { _visitor.AddConstant(constant.Key, constant.Value); } } Expression countExpression = null; if (item.CountOption.GetValueOrDefault()) { MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(itemType); countExpression = Expression.Call(countMethodInfo, expression); } if (item.SelectAndExpand.SelectedItems.Any()) { var path = new ODataPath(_path.Union(item.PathToNavigationProperty)); var selectTranslator = new OeSelectTranslator(_visitor, path); Expression nestedExpression = selectTranslator.CreateExpression(expression, item.SelectAndExpand, OeMetadataLevel.Minimal); Type nestedType = OeExpressionHelper.GetCollectionItemType(nestedExpression.Type); if (nestedType == null) { var visitor = new ParameterVisitor(selectTranslator._parameter, expression); nestedExpression = visitor.Visit(nestedExpression); nestedType = nestedExpression.Type; } _selectItemInfo.EntryFactory = selectTranslator.CreateNestedEntryFactory(nestedType, _selectItemInfo.EntitySet, _selectItemInfo.ResourceInfo); expression = nestedExpression; } if (countExpression != null) { return(CreateNavigationLinkInfo(navigationItemType, expression, countExpression)); } return(expression); }
public Expression CreateCountExpression(IQueryable query, Expression expression) { Type filterType = EntryFactory == null ? query.ElementType : EdmModel.GetClrType(EntryFactory.EntityType); Expression filterExpression = ODataUri.Filter == null ? query.Expression : FilterVisitor.Translate(query, expression, filterType); Type sourceType = OeExpressionHelper.GetCollectionItemType(filterExpression.Type); MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType); return(Expression.Call(countMethodInfo, filterExpression)); }
public Expression Build(Expression source, IReadOnlyList <OeSkipTokenNameValue> skipTokenNameValues, OrderByClause uniqueOrderBy) { OrderProperty[] orderProperties = CreateOrderProperies(source, _visitor, skipTokenNameValues, uniqueOrderBy); Expression filter = CreateFilterExpression(_visitor, _isDatabaseNullHighestValue, orderProperties); LambdaExpression lambda = Expression.Lambda(filter, _visitor.Parameter); MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(_visitor.Parameter.Type); return(Expression.Call(whereMethodInfo, source, lambda)); }
public Expression Build(Expression source, String skipToken) { OrderProperty[] orderProperties = CreateOrderProperies(_skipTokenParser, skipToken); Expression filter = CreateFilterExpression(source, _visitor, _skipTokenParser.IsDatabaseNullHighestValue, orderProperties); LambdaExpression lambda = Expression.Lambda(filter, _visitor.Parameter); MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(_visitor.Parameter.Type); return(Expression.Call(whereMethodInfo, source, lambda)); }
public Expression ApplyCount(Expression source, bool?queryCount) { if (!queryCount.GetValueOrDefault()) { return(source); } MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(ParameterType); return(Expression.Call(countMethodInfo, source)); }
public Expression ApplySkip(Expression source, long?skip, ODataPath path) { if (skip == null) { return(source); } ConstantExpression skipConstant = Visitor.AddSkipConstant((int)skip.Value, path); MethodInfo skipMethodInfo = OeMethodInfoHelper.GetSkipMethodInfo(ParameterType); return(Expression.Call(skipMethodInfo, source, skipConstant)); }
private static MethodCallExpression CountDistinctExpression(ParameterExpression sourceParameter, LambdaExpression lambda) { MethodInfo selectMetodInfo = OeMethodInfoHelper.GetSelectMethodInfo(lambda.Parameters[0].Type, lambda.ReturnType); MethodCallExpression selectCall = Expression.Call(selectMetodInfo, sourceParameter, lambda); MethodInfo distinctMethodInfo = OeMethodInfoHelper.GetDistinctMethodInfo(lambda.ReturnType); MethodCallExpression distinctCall = Expression.Call(distinctMethodInfo, selectCall); MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(lambda.ReturnType); return(Expression.Call(countMethodInfo, distinctCall)); }
public Expression ApplyTake(Expression source, long?top, ODataPath path) { if (top == null) { return(source); } ConstantExpression topConstant = Visitor.AddTopConstant((int)top.Value, path); MethodInfo takeMethodInfo = OeMethodInfoHelper.GetTakeMethodInfo(ParameterType); return(Expression.Call(takeMethodInfo, source, topConstant)); }
private Expression CreateExpression(Expression source, SelectExpandClause selectClause, OeMetadataLevel metadatLevel) { Type itemType = OeExpressionHelper.GetCollectionItemType(source.Type); if (itemType == null) { _parameter = Expression.Parameter(source.Type); } else { _parameter = Expression.Parameter(itemType); } var expressions = new List <Expression>(); foreach (SelectItem selectItem in selectClause.SelectedItems) { Expression expression = selectItem.TranslateWith(this); if (SelectItemInfoExists(_selectItemInfo.EdmProperty)) { continue; } expressions.Add(expression); _selectItemInfos.Add(_selectItemInfo); } if (_pathSelect) { if (metadatLevel == OeMetadataLevel.Full) { AddKey(itemType, expressions); } } else { expressions.Insert(0, _parameter); } NewExpression newExpression = OeExpressionHelper.CreateTupleExpression(expressions); if (itemType == null) { return(newExpression); } LambdaExpression lambda = Expression.Lambda(newExpression, _parameter); MethodInfo selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(_parameter.Type, newExpression.Type); return(Expression.Call(selectMethodInfo, source, lambda)); }
public Expression ApplyFilter(Expression source, FilterClause filterClause) { if (filterClause == null) { return(source); } Expression e = Visitor.TranslateNode(filterClause.Expression); LambdaExpression lambda = Expression.Lambda(e, Visitor.Parameter); MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(ParameterType); return(Expression.Call(whereMethodInfo, source, lambda)); }
private Expression ApplyThenBy(Expression source, OrderByClause thenByClause) { if (thenByClause == null) { return(source); } Expression e = _visitor.TranslateNode(thenByClause.Expression); LambdaExpression lambda = Expression.Lambda(e, Parameter); MethodInfo thenByMethodInfo = thenByClause.Direction == OrderByDirection.Ascending ? OeMethodInfoHelper.GetThenByMethodInfo(ParameterType, e.Type) : OeMethodInfoHelper.GetThenByDescendingMethodInfo(ParameterType, e.Type); MethodCallExpression thenByCall = Expression.Call(thenByMethodInfo, source, lambda); return(ApplyThenBy(thenByCall, thenByClause.ThenBy)); }
private MethodCallExpression GetJoin(Expression innerSource, IEdmNavigationProperty navigationProperty) { Type outerType = OeExpressionHelper.GetCollectionItemType(_outerSource.Type); Type innerType = OeExpressionHelper.GetCollectionItemType(innerSource.Type); var joinBuilder = new OeJoinBuilder(new OeQueryNodeVisitor(_outerParameterExpression)); (LambdaExpression outerKeySelector, LambdaExpression innerKeySelector) = joinBuilder.GetJoinKeySelector(outerType, innerType, Array.Empty <IEdmNavigationProperty>(), navigationProperty); var replaceParameterVisitor = new ReplaceParameterVisitor(_outerParameterExpression, outerKeySelector.Parameters[0]); Expression outerKeyExpression = replaceParameterVisitor.Visit(outerKeySelector.Body); IReadOnlyList <MemberExpression> outerKeyProperties; IReadOnlyList <MemberExpression> innerKeyProperties; if (OeExpressionHelper.IsTupleType(outerKeySelector.ReturnType)) { outerKeyProperties = OeExpressionHelper.GetPropertyExpressions(outerKeyExpression); innerKeyProperties = OeExpressionHelper.GetPropertyExpressions(innerKeySelector.Body); } else { outerKeyProperties = new MemberExpression[] { (MemberExpression)outerKeyExpression }; innerKeyProperties = new MemberExpression[] { (MemberExpression)innerKeySelector.Body }; } BinaryExpression?joinExpression = null; for (int i = 0; i < outerKeyProperties.Count; i++) { if (joinExpression == null) { joinExpression = Expression.MakeBinary(ExpressionType.Equal, outerKeyProperties[i], innerKeyProperties[i]); } else { BinaryExpression equal = Expression.MakeBinary(ExpressionType.Equal, outerKeyProperties[i], innerKeyProperties[i]); joinExpression = Expression.MakeBinary(ExpressionType.AndAlso, joinExpression, equal); } } MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(innerType); LambdaExpression joinLambda = Expression.Lambda(joinExpression !, innerKeySelector.Parameters); return(Expression.Call(whereMethodInfo, innerSource, joinLambda)); }
public static MethodCallExpression CreateCountExpression(Expression expression) { var filterVisitor = new FilterVisitor(); filterVisitor.Visit(expression); Expression whereExpression = filterVisitor.WhereExpression; if (whereExpression == null) { whereExpression = filterVisitor.Source; } Type sourceType = OeExpressionHelper.GetCollectionItemType(whereExpression.Type); MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType); return(Expression.Call(countMethodInfo, whereExpression)); }
private MethodCallExpression ApplyFilter(Expression source, FilterTransformationNode transformation) { Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type); ParameterExpression sourceParameter = Expression.Parameter(sourceType); var visitor = CreateVisitor(sourceParameter); if (_aggProperties.Count > 0) { visitor.TuplePropertyByAliasName = GetTuplePropertyByAliasName; } Expression e = visitor.TranslateNode(transformation.FilterClause.Expression); MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(sourceParameter.Type); LambdaExpression lambda = Expression.Lambda(e, sourceParameter); return(Expression.Call(whereMethodInfo, source, lambda)); }
private MethodCallExpression ApplyAggregate(Expression source, AggregateTransformationNode transformation) { Type sourceType = OeExpressionHelper.GetCollectionItemType(source.Type); ParameterExpression sourceParameter = Expression.Parameter(sourceType); ParameterExpression lambdaParameter = sourceParameter; var expressions = new List <Expression>(); if (sourceType.GetGenericTypeDefinition() == typeof(IGrouping <,>)) { PropertyInfo keyProperty = sourceType.GetProperty(nameof(IGrouping <Object, Object> .Key)); MemberExpression key = Expression.Property(sourceParameter, keyProperty); expressions.Add(key); lambdaParameter = Expression.Parameter(sourceType.GetGenericArguments()[1]); } var visitor = CreateVisitor(lambdaParameter); foreach (AggregateExpression aggExpression in transformation.Expressions) { LambdaExpression aggLambda = null; if (aggExpression.Expression.Kind != QueryNodeKind.Count) { Expression e = visitor.TranslateNode(aggExpression.Expression); aggLambda = Expression.Lambda(e, lambdaParameter); } MethodCallExpression aggCallExpression = AggCallExpression(aggExpression.Method, sourceParameter, aggLambda); expressions.Add(aggCallExpression); _aggProperties.Add(CreateEdmProperty(_visitor.EdmModel, aggCallExpression.Type, aggExpression.Alias, false)); } NewExpression newExpression = OeExpressionHelper.CreateTupleExpression(expressions); MethodInfo selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(sourceType, newExpression.Type); LambdaExpression lambda = Expression.Lambda(newExpression, sourceParameter); return(Expression.Call(selectMethodInfo, source, lambda)); }
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)); }
public MethodCallExpression CreateCountExpression(Expression source) { if (EntryFactory == null) { return(null); } Type sourceType = EdmModel.GetClrType(EntryFactory.EntitySet); var filterVisitor = new FilterVisitor(sourceType); filterVisitor.Visit(source); Expression whereExpression = filterVisitor.WhereExpression; if (whereExpression == null) { whereExpression = filterVisitor.Source; } MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType); return(Expression.Call(countMethodInfo, whereExpression)); }
public MethodCallExpression CreateCountExpression(Expression source) { if (EntryFactory == null) { throw new InvalidOperationException("Cannot get count expression for scalar result expression"); } Type sourceType = EdmModel.GetClrType(EntryFactory.EntitySet); var filterVisitor = new FilterVisitor(sourceType); filterVisitor.Visit(source); Expression?whereExpression = filterVisitor.WhereExpression; if (whereExpression == null) { whereExpression = filterVisitor.Source; } MethodInfo countMethodInfo = OeMethodInfoHelper.GetCountMethodInfo(sourceType); return(Expression.Call(countMethodInfo, whereExpression)); }
private static MethodInfo GetThenByMethodInfo(OrderByDirection direction, Type sourceType, Type keyType) { return(direction == OrderByDirection.Ascending ? OeMethodInfoHelper.GetThenByMethodInfo(sourceType, keyType) : OeMethodInfoHelper.GetThenByDescendingMethodInfo(sourceType, keyType)); }