public void ChangeParameterType(Expression source) { Type itemType = OeExpressionHelper.GetCollectionItemTypeOrNull(source.Type) ?? source.Type; if (Parameter.Type != itemType) { _parameter = Expression.Parameter(itemType); } }
protected override Expression VisitConstant(ConstantExpression node) { if (OeExpressionHelper.GetCollectionItemTypeOrNull(node.Type) == _sourceType) { _source = node; } return(node); }
private static bool GetIsTuple(LambdaExpression linkAccessor) { if (linkAccessor != null && ((MemberExpression)linkAccessor.Body).Expression is UnaryExpression unaryExpression) { return(OeExpressionHelper.IsTupleType(unaryExpression.Type)); } return(false); }
private NewExpression CreateTupleExpression() { var expressions = new Expression[_selectItemInfos.Count]; for (int i = 0; i < expressions.Length; i++) { expressions[i] = _selectItemInfos[i].Expression; } return(OeExpressionHelper.CreateTupleExpression(expressions)); }
protected virtual IReadOnlyList <Expression> TranslateParameters( IReadOnlyList <ConstantExpression> constantExpressions, IReadOnlyDictionary <ConstantExpression, ConstantNode> constantsMapping) { NewExpression tupleNew = OeExpressionHelper.CreateTupleExpression(constantExpressions); var tupleCtor = (Func <Object>)Expression.Lambda(tupleNew).Compile(); Object tuple = tupleCtor(); return(OeExpressionHelper.GetPropertyExpressions(Expression.Constant(tuple))); }
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 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)); }
public override Expression Visit(SingleValuePropertyAccessNode nodeIn) { Expression e; if (TuplePropertyByAliasName == null) { e = TranslateNode(nodeIn.Source); PropertyInfo property = e.Type.GetProperty(nodeIn.Property.Name); if (property == null) { if (!OeExpressionHelper.IsTupleType(e.Type)) { throw new InvalidOperationException("must by Tuple " + e.Type.ToString()); } IEdmNavigationSource navigationSource = ((ResourceRangeVariableReferenceNode)nodeIn.Source).NavigationSource; property = GetTuplePropertyByEntityType(e.Type, navigationSource.EntityType()); if (property == null) { if (TuplePropertyByEdmProperty == null) { throw new InvalidOperationException("entity type " + navigationSource.EntityType().FullName() + " not found in tuple properties"); } return(TuplePropertyByEdmProperty(Parameter, nodeIn.Property)); } else { e = Expression.Property(e, property); property = e.Type.GetProperty(nodeIn.Property.Name); } } return(Expression.Property(e, property)); } Expression source = TranslateNode(nodeIn.Source); if (source == null) { var navigationNode = (SingleNavigationNode)nodeIn.Source; String aliasName = navigationNode.NavigationProperty.Name + "_" + nodeIn.Property.Name; return(TuplePropertyByAliasName(Parameter, aliasName)); } e = TuplePropertyByAliasName(source, nodeIn.Property.Name); if (e == null) { e = GetPropertyExpression(nodeIn); if (e == null) { throw new InvalidOperationException("property name " + nodeIn.Property.Name + " not found"); } } return(e); }
protected override Expression VisitConstant(ConstantExpression node) { Type sourceType = OeExpressionHelper.GetCollectionItemType(node.Type); if (sourceType != null) { Source = node; _sourceType = sourceType; } return(node); }
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) { for (int i = 0; i < node.ChildTransformations.Count; i++) { Expression e = visitor.TranslateNode(node.ChildTransformations[i].Expression); expressions.Add(e); String aliasName = node.Name + "_" + node.ChildTransformations[i].Name; _aggProperties.Add(CreateEdmProperty(visitor.EdmModel, e.Type, aliasName, 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 Visit(BinaryOperatorNode nodeIn) { Expression left = TranslateNode(nodeIn.Left); Expression right = TranslateNode(nodeIn.Right); if (left.Type != right.Type && !(OeExpressionHelper.IsNull(left) || OeExpressionHelper.IsNull(right))) { Type leftType = left.Type; Type rightType = right.Type; if (OeExpressionHelper.IsNullable(left)) { leftType = Nullable.GetUnderlyingType(left.Type); left = Expression.Convert(left, left.Type); } else if (OeExpressionHelper.IsNullable(right)) { rightType = Nullable.GetUnderlyingType(right.Type); right = Expression.Convert(right, right.Type); } if (right.Type != left.Type) { if (left is ConstantExpression) { ConstantExpression oldConstant = left as ConstantExpression; ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(oldConstant, rightType); if (oldConstant != newConstant) { ReplaceConstant(oldConstant, newConstant); } left = Expression.Convert(newConstant, right.Type); } else if (right is ConstantExpression) { ConstantExpression oldConstant = right as ConstantExpression; ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(oldConstant, leftType); if (oldConstant != newConstant) { ReplaceConstant(oldConstant, newConstant); } right = Expression.Convert(newConstant, left.Type); } else { right = Expression.Convert(right, left.Type); } } } ExpressionType binaryType = OeExpressionHelper.ToExpressionType(nodeIn.OperatorKind); return(Expression.MakeBinary(binaryType, left, right)); }
private Expression Lambda(CollectionNavigationNode sourceNode, SingleValueNode body, String methodName) { Expression source = TranslateNode(sourceNode); PropertyInfo sourceNavigationProperty = Parameter.Type.GetProperty(sourceNode.NavigationProperty.Name); Type targetType = OeExpressionHelper.GetCollectionItemType(sourceNavigationProperty.PropertyType); ParameterExpression parameter = Expression.Parameter(targetType); Expression bodyExression = new OeQueryNodeVisitor(this, parameter).TranslateNode(body); LambdaExpression lambda = Expression.Lambda(bodyExression, parameter); return(Expression.Call(typeof(Enumerable), methodName, new Type[] { targetType }, source, lambda)); }
private OeEntryFactory CreateEntryFactory(OeExpressionBuilder expressionBuilder, Expression source) { IEdmEntitySet entitySet = EntitySet; Type itemType = OeExpressionHelper.GetCollectionItemType(source.Type); if (!OeExpressionHelper.IsTupleType(itemType) && itemType != EntitySetAdapter.EntityType) { entitySet = OeEdmClrHelper.GetEntitySet(EdmModel, itemType); } return(expressionBuilder.CreateEntryFactory(entitySet)); }
private IEdmNavigationProperty GetEdmNavigationProperty(Db.OeDataAdapter dataAdapter, MemberExpression navigationProperty) { Type outerItemType = OeExpressionHelper.GetCollectionItemType(_outerSource.Type); Db.OeEntitySetAdapter?outerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(outerItemType); if (outerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + outerItemType.Name); } IEdmEntitySet outerEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, outerEntitySetAdapter.EntitySetName); return(outerEntitySet.EntityType().NavigationProperties().Single(p => p.Name == navigationProperty.Member.Name)); }
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 OeEntryFactory(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors, OePropertyAccessor[] skipTokenAccessors) { Array.Sort(accessors, AccessorByNameComparer.Instance); EntitySet = entitySet; _allAccessors = accessors; Accessors = GetAccessorsWithoutSkiptoken(accessors); SkipTokenAccessors = skipTokenAccessors; EdmEntityType = entitySet.EntityType(); NavigationLinks = Array.Empty <OeEntryFactory>(); _typeName = EdmEntityType.FullName(); IsTuple = accessors.Length == 0 ? false : OeExpressionHelper.IsTupleType(accessors[0].PropertyExpression.Expression.Type); }
protected override Expression VisitMember(MemberExpression node) { var e = (MemberExpression)base.VisitMember(node); if (!_navigationPropertyCanBeNull) { return(e); } Type nullableType = e.Type.IsClass || OeExpressionHelper.IsNullable(e) ? e.Type : typeof(Nullable <>).MakeGenericType(e.Type); return(Expression.Condition(Expression.Equal(e.Expression, OeConstantToVariableVisitor.NullConstantExpression), Expression.Convert(OeConstantToVariableVisitor.NullConstantExpression, nullableType), nullableType == e.Type ? (Expression)e : Expression.Convert(e, nullableType))); }
protected override Expression VisitNew(NewExpression node) { if (_navigationPropertyCanBeNull) { var expressions = new Expression[node.Arguments.Count]; for (int i = 0; i < expressions.Length; i++) { expressions[i] = base.Visit(node.Arguments[i]); } return(OeExpressionHelper.CreateTupleExpression(expressions)); } return(base.VisitNew(node)); }
private static FilterClause CreateFilterClause(IEdmEntitySet entitySet, IEnumerable <KeyValuePair <String, Object> > keys) { ResourceRangeVariableReferenceNode refNode = OeEdmClrHelper.CreateRangeVariableReferenceNode(entitySet); var entityType = (IEdmEntityType)refNode.RangeVariable.TypeReference.Definition; var propertyValues = new List <KeyValuePair <IEdmStructuralProperty, Object> >(); foreach (KeyValuePair <String, Object> keyValue in keys) { var property = (IEdmStructuralProperty)entityType.GetPropertyIgnoreCase(keyValue.Key); propertyValues.Add(new KeyValuePair <IEdmStructuralProperty, Object>(property, keyValue.Value)); } return(new FilterClause(OeExpressionHelper.CreateFilterExpression(refNode, propertyValues), refNode.RangeVariable)); }
public Expression Translate(Expression expression, IReadOnlyList <Db.OeQueryCacheDbParameterValue> parameterValues) { _parameterValues = parameterValues; base.Visit(expression); if (_constantExpressions.Count == 0) { return(expression); } NewExpression tupleNew = OeExpressionHelper.CreateTupleExpression(_constantExpressions); var tupleCtor = (Func <Object>)LambdaExpression.Lambda(tupleNew).Compile(); Object tuple = tupleCtor(); _parameterExpressions = OeExpressionHelper.GetPropertyExpressions(Expression.Constant(tuple)); return(base.Visit(expression)); }
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 OePropertyAccessor[] GetAccessors(Expression source, OrderByClause orderByClause, Translators.OeJoinBuilder joinBuilder) { var accessors = new List <OePropertyAccessor>(); ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, OeExpressionHelper.GetCollectionItemType(source.Type)); while (orderByClause != null) { var propertyNode = (SingleValuePropertyAccessNode)orderByClause.Expression; MemberExpression propertyExpression = joinBuilder.GetJoinPropertyExpression(source, instance, propertyNode); accessors.Add(OePropertyAccessor.CreatePropertyAccessor(propertyNode.Property, propertyExpression, parameter, true)); orderByClause = orderByClause.ThenBy; } return(accessors.ToArray()); }
private Expression GetPropertyExpression(SingleValuePropertyAccessNode nodeIn) { Expression e = TranslateNode(nodeIn.Source); PropertyInfo property = e.Type.GetPropertyIgnoreCase(nodeIn.Property); if (property == null) { if (!OeExpressionHelper.IsTupleType(e.Type)) { throw new InvalidOperationException("must by Tuple " + e.Type.ToString()); } IEdmNavigationSource navigationSource = ((ResourceRangeVariableReferenceNode)nodeIn.Source).NavigationSource; property = GetTuplePropertyByEntityType(e.Type, navigationSource.EntityType()); } return(Expression.Property(e, property)); }
public static OePropertyAccessor[] GetAccessors(Expression source, OrderByClause orderByClause, Translators.OeJoinBuilder joinBuilder) { var accessors = new List <OePropertyAccessor>(); ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, OeExpressionHelper.GetCollectionItemType(source.Type)); while (orderByClause != null) { MemberExpression propertyExpression = Translators.OeOrderByTranslator.GetPropertyExpression(joinBuilder, source, instance, orderByClause.Expression); IEdmStructuralProperty edmProperty = GetEdmProperty(orderByClause.Expression, propertyExpression.Type); accessors.Add(OePropertyAccessor.CreatePropertyAccessor(edmProperty, propertyExpression, parameter, true)); orderByClause = orderByClause.ThenBy; } return(accessors.ToArray()); }
public Expression GetTuplePropertyByAliasName(Expression source, SingleValueNode singleValueNode) { String aliasName = GetAliasName(singleValueNode); int i = _aggProperties.FindIndex(p => p.Name == aliasName); if (_aggProperties[i].IsGroup) { return(OeExpressionHelper.GetPropertyExpressions(_aggExpressions[0])[i]); } int groupCount; for (groupCount = 0; groupCount < _aggProperties.Count && _aggProperties[groupCount].IsGroup; groupCount++) { } return(_aggExpressions[i - groupCount]); }
public static OePropertyAccessor[] GetAccessors(Expression source, OrderByClause orderByClause, Translators.OeJoinBuilder joinBuilder) { var accessors = new List <OePropertyAccessor>(); ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, OeExpressionHelper.GetCollectionItemType(source.Type)); while (orderByClause != null) { MemberExpression propertyExpression = Translators.OeOrderByTranslator.GetPropertyExpression(joinBuilder, source, instance, orderByClause.Expression); IEdmStructuralProperty edmProperty = GetEdmProperty(orderByClause.Expression, propertyExpression.Type); OePropertyAccessor accessor; if (typeof(OeDynamicType).IsAssignableFrom(propertyExpression.Expression !.Type)) { PropertyInfo indexProperty = typeof(OeDynamicType).GetProperty("Item") !; MethodCallExpression expression = Expression.Call(propertyExpression.Expression !, indexProperty.GetGetMethod() !, Expression.Constant(edmProperty.Name)); accessor = OePropertyAccessor.CreatePropertyAccessor(edmProperty, expression, parameter, true); }
private Expression Lambda(CollectionNavigationNode sourceNode, SingleValueNode body, String methodName) { Expression source = TranslateNode(sourceNode); PropertyInfo sourceNavigationProperty = Parameter.Type.GetProperty(sourceNode.NavigationProperty.Name); Type targetType = OeExpressionHelper.GetCollectionItemType(sourceNavigationProperty.PropertyType); ParameterExpression it = Expression.Parameter(targetType); _parameters.Push(it); var bodyExression = TranslateNode(body); _parameters.Pop(); LambdaExpression lambda = Expression.Lambda(bodyExression, it); var typeArguments = new Type[] { it.Type }; return(Expression.Call(typeof(Enumerable), methodName, typeArguments, source, lambda)); }
public Expression ApplySelect(Expression source, SelectExpandClause selectClause, ODataPath path, OeMetadataLevel metadatLevel) { if (selectClause == null) { return(source); } var selectTranslator = new OeSelectTranslator(_visitor, path); Expression selectExpression = selectTranslator.Build(source, selectClause, metadatLevel); _entryFactory = selectTranslator.CreateEntryFactory; Type selectItemType = OeExpressionHelper.GetCollectionItemType(selectExpression.Type); _visitor = new OeQueryNodeVisitor(_model, Expression.Parameter(selectItemType), _visitor.Constans); return(selectExpression); }
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)); }