public Expression ApplyFilter(Expression source, FilterClause filterClause) { if (filterClause == null) { return(source); } Expression e = _visitor.TranslateNode(filterClause.Expression); LambdaExpression lambda = Expression.Lambda(e, Parameter); MethodInfo whereMethodInfo = OeMethodInfoHelper.GetWhereMethodInfo(ParameterType); return(Expression.Call(whereMethodInfo, 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); }
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 void BuildCompute(ComputeClause computeClause) { foreach (ComputeExpression computeExpression in computeClause.ComputedItems) { Expression expression = _visitor.TranslateNode(computeExpression.Expression); IEdmTypeReference edmTypeReference = OeEdmClrHelper.GetEdmTypeReference(_model, expression.Type); _selectItemInfos.Add(new SelectItemInfo(new ComputeProperty(computeExpression.Alias, edmTypeReference), expression)); } }
public Expression ApplyOrderBy(Expression source, OrderByClause orderByClause, out bool isInsertedOrderByMethod) { isInsertedOrderByMethod = _isInsertedOrderByMethod; if (orderByClause == null) { return(source); } Expression keySelector = null; if (!_isInsertedOrderByMethod) { var tupleProperty = new OePropertyTranslator(source); _visitor.TuplePropertyByEdmProperty = tupleProperty.Build; if (OeExpressionHelper.IsTupleType(_visitor.Parameter.Type)) { var propertyNode = (SingleValuePropertyAccessNode)orderByClause.Expression; keySelector = tupleProperty.Build(_visitor.Parameter, propertyNode.Property); } if (keySelector == null) { keySelector = _visitor.TranslateNode(orderByClause.Expression); } } if (keySelector == null) { var propertyNode = orderByClause.Expression as SingleValuePropertyAccessNode; if (propertyNode == null) { throw new NotSupportedException("rewrite expression support only sort by property"); } IEdmType edmSplitType; if (propertyNode.Source is SingleNavigationNode navigationNode) { while (navigationNode.Source is SingleNavigationNode) { navigationNode = navigationNode.Source as SingleNavigationNode; } edmSplitType = navigationNode.NavigationProperty.DeclaringType; } else { edmSplitType = propertyNode.Property.DeclaringType; } isInsertedOrderByMethod = true; return(InsertOrderByMethod(source, orderByClause, edmSplitType)); } return(GetOrderByExpression(source, _visitor.Parameter, orderByClause.Direction, keySelector)); }
private Expression InsertOrderByMethod(Expression source, OrderByClause orderByClause, IEdmType edmSplitType) { Type sourceItemType = _visitor.EdmModel.GetClrType(edmSplitType); Type sourceTypeGeneric = _isInsertedOrderByMethod ? typeof(IOrderedEnumerable <>) : typeof(IEnumerable <>); var splitterVisitor = new OeExpressionSplitterVisitor(sourceTypeGeneric.MakeGenericType(sourceItemType)); Expression beforeExpression = splitterVisitor.GetBefore(source); var visitor = new OeQueryNodeVisitor(_visitor.EdmModel, Expression.Parameter(sourceItemType), _visitor.Constans); Expression keySelector = visitor.TranslateNode(orderByClause.Expression); Expression orderByCall = GetOrderByExpression(beforeExpression, visitor.Parameter, orderByClause.Direction, keySelector); return(splitterVisitor.Join(orderByCall)); }
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)); }
private static Expression CreateFilterExpression(Expression source, OeQueryNodeVisitor visitor, bool isDatabaseNullHighestValue, OrderProperty[] orderProperties) { var tupleProperty = new OePropertyTranslator(source); Expression filter = null; for (int i = 0; i < orderProperties.Length; i++) { BinaryExpression eqFilter = null; for (int j = 0; j < i; j++) { MemberExpression propertyExpression = orderProperties[j].PropertyExpression; ConstantExpression parameterExpression = orderProperties[j].ParmeterExpression; BinaryExpression eq = Expression.Equal(propertyExpression, parameterExpression); if (OeExpressionHelper.IsNullable(propertyExpression)) { UnaryExpression typedNull = Expression.Convert(OeConstantToVariableVisitor.NullConstantExpression, parameterExpression.Type); BinaryExpression isNull = Expression.Equal(parameterExpression, typedNull); eq = Expression.OrElse(eq, isNull); } eqFilter = eqFilter == null ? eq : Expression.AndAlso(eqFilter, eq); } orderProperties[i].PropertyExpression = (MemberExpression)visitor.TranslateNode(orderProperties[i].PropertyNode); if (orderProperties[i].PropertyExpression == null) { orderProperties[i].PropertyExpression = tupleProperty.Build(visitor.Parameter, orderProperties[i].PropertyNode.Property); } BinaryExpression ge = CreateBinaryExpression(visitor, isDatabaseNullHighestValue, ref orderProperties[i]); eqFilter = eqFilter == null ? ge : Expression.AndAlso(eqFilter, ge); filter = filter == null ? eqFilter : Expression.OrElse(filter, eqFilter); } return(filter); }
public static Expression Bind(OeQueryNodeVisitor visitor, SingleValueFunctionCallNode nodeIn) { var expressions = new List <Expression>(2); foreach (QueryNode node in nodeIn.Parameters) { expressions.Add(visitor.TranslateNode(node)); } if (OeExpressionHelper.IsNullable(expressions[0])) { MethodInfo getValueOrDefault = expressions[0].Type.GetMethod("GetValueOrDefault", Type.EmptyTypes); MethodCallExpression callExpression = Expression.Call(expressions[0], getValueOrDefault); expressions[0] = callExpression; } bool isProperty = false; string name; switch (nodeIn.Name) { case "cast": return(CastFunction(nodeIn, expressions)); case "ceiling": return(CeilingFunction(expressions)); case "concat": return(ConcatFunction(expressions)); case "contains": name = "Contains"; break; case "day": name = "Day"; isProperty = true; break; case "endswith": name = "EndsWith"; break; case "floor": return(FloorFunction(expressions)); case "fractionalseconds": return(FractionalSecondsFunction(expressions)); case "hour": name = "Hour"; isProperty = true; break; case "indexof": name = "IndexOf"; break; case "length": name = "Length"; isProperty = true; break; case "minute": name = "Minute"; isProperty = true; break; case "month": name = "Month"; isProperty = true; break; case "round": return(RoundFunction(expressions)); case "second": name = "Second"; isProperty = true; break; case "startswith": name = "StartsWith"; break; case "substring": name = "Substring"; break; case "tolower": name = "ToLower"; break; case "toupper": name = "ToUpper"; break; case "trim": name = "Trim"; break; case "year": name = "Year"; isProperty = true; break; default: throw new NotImplementedException(nodeIn.Name); } MethodInfo methodInfo; PropertyInfo propertyInfo; switch (expressions.Count) { case 1: if (isProperty) { propertyInfo = expressions[0].Type.GetProperty(name); return(Expression.Property(expressions[0], propertyInfo)); } else { methodInfo = expressions[0].Type.GetMethod(name, Type.EmptyTypes); return(Expression.Call(expressions[0], methodInfo)); } case 2: methodInfo = expressions[0].Type.GetMethod(name, new Type[] { expressions[1].Type }); return(Expression.Call(expressions[0], methodInfo, expressions[1])); case 3: methodInfo = expressions[0].Type.GetMethod(name, new Type[] { expressions[1].Type, expressions[2].Type }); return(Expression.Call(expressions[0], methodInfo, expressions[1], expressions[2])); default: throw new NotImplementedException(name); } }