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.GetTypeInfo().GetProperty(nameof(IGrouping <Object, Object> .Key)); MemberExpression key = Expression.Property(sourceParameter, keyProperty); expressions.Add(key); lambdaParameter = Expression.Parameter(sourceType.GetTypeInfo().GetGenericArguments()[1]); } var visitor = CreateVisitor(lambdaParameter); foreach (AggregateExpression aggExpression in transformation.Expressions) { Expression e = visitor.TranslateNode(aggExpression.Expression); LambdaExpression 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)); }
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); }
private MethodCallExpression CreateSelectExpression(Expression source, ParameterExpression parameter) { NewExpression newExpression = CreateTupleExpression(); LambdaExpression lambda = Expression.Lambda(newExpression, parameter); MethodInfo selectMethodInfo = OeMethodInfoHelper.GetSelectMethodInfo(parameter.Type, newExpression.Type); return(Expression.Call(selectMethodInfo, source, lambda)); }
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); }
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)); }
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)); }
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)); }
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)); }