public void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree, string sourceAlias, bool userInnerJoin = false) { var join = tree.TreeBuilder.Dot( tree.TreeBuilder.Ident(sourceAlias), tree.TreeBuilder.Ident(resultOperator.RelationMember.Name)); string alias = queryModelVisitor.Model.GetNewName("_"); if (userInnerJoin) { tree.AddFromClause(tree.TreeBuilder.FetchJoin(join, tree.TreeBuilder.Alias(alias))); } else { tree.AddFromClause(tree.TreeBuilder.LeftFetchJoin(join, tree.TreeBuilder.Alias(alias))); } tree.AddDistinctRootOperator(); foreach (var innerFetch in resultOperator.InnerFetchRequests) { if (innerFetch is InnerFetchOneRequest || innerFetch is InnerFetchManyRequest) { Process(innerFetch, queryModelVisitor, tree, alias, true); } else { Process(innerFetch, queryModelVisitor, tree, alias); } } }
private QueryModelVisitor(VisitorParameters visitorParameters, bool root, QueryModel queryModel) { VisitorParameters = visitorParameters; Model = queryModel; _hqlTree = new IntermediateHqlTree(root); }
private QueryModelVisitor(VisitorParameters visitorParameters, bool root, QueryModel queryModel, NhLinqExpressionReturnType?rootReturnType) { VisitorParameters = visitorParameters; Model = queryModel; _rootReturnType = root ? rootReturnType : null; _hqlTree = new IntermediateHqlTree(root); }
private void Process( FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree, HqlTreeNode currentNode, string sourceAlias) { var memberPath = tree.TreeBuilder.Dot( tree.TreeBuilder.Ident(sourceAlias), tree.TreeBuilder.Ident(resultOperator.RelationMember.Name)); Process(resultOperator, queryModelVisitor, tree, memberPath, currentNode, null); }
protected static void AddClientSideEval(MethodInfo target, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { target = target.MakeGenericMethod(queryModelVisitor.CurrentEvaluationType.DataType); var parameter = Expression.Parameter(queryModelVisitor.PreviousEvaluationType.DataType, null); var lambda = Expression.Lambda( Expression.Call( target, parameter), parameter); tree.AddPostExecuteTransformer(lambda); }
protected static void AddClientSideEval(MethodInfo target, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var type = queryModelVisitor.Model.SelectClause.Selector.Type; target = target.MakeGenericMethod(type); var parameter = Expression.Parameter(typeof(IQueryable<>).MakeGenericType(type), null); var lambda = Expression.Lambda( Expression.Call( target, parameter), parameter); tree.AddPostExecuteTransformer(lambda); }
internal static void Process(IntermediateHqlTree tree) { if (tree.IsRoot) { tree.AddTakeClause(tree.TreeBuilder.Constant(1)); Expression <Func <IEnumerable <object>, bool> > x = l => l.Any(); tree.AddListTransformer(x); // NH-3850: Queries with polymorphism yields many results which must be combined. Expression <Func <IEnumerable <bool>, bool> > px = l => l.Any(r => r); tree.AddPostExecuteTransformer(px); } else { tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)); } }
public void Process(OfTypeResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var source = queryModelVisitor.Model.SelectClause.GetOutputDataInfo().ItemExpression; var expression = new HqlGeneratorExpressionTreeVisitor(queryModelVisitor.VisitorParameters) .BuildOfType(source, resultOperator.SearchedItemType); tree.AddWhereClause(expression); }
public void Process(ContainsResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var itemExpression = HqlGeneratorExpressionVisitor.Visit(resultOperator.Item, queryModelVisitor.VisitorParameters) .AsExpression(); var from = GetFromRangeClause(tree.Root); var source = from.Children.First(); if (source is HqlParameter) { // This is an "in" style statement if (IsEmptyList((HqlParameter)source, queryModelVisitor.VisitorParameters)) { // if the list is empty the expression will always be false, so generate "1 = 0" tree.SetRoot(tree.TreeBuilder.Equality(tree.TreeBuilder.Constant(1), tree.TreeBuilder.Constant(0))); } else { tree.SetRoot(tree.TreeBuilder.In(itemExpression, source)); } } else { // This is an "exists" style statement if (itemExpression is HqlParameter) { tree.AddWhereClause(tree.TreeBuilder.Equality( tree.TreeBuilder.Ident(GetFromAlias(tree.Root).AstNode.Text), itemExpression)); ProcessAny.Process(tree); } else { tree.SetRoot(tree.TreeBuilder.In(itemExpression, tree.Root)); } } }
public abstract void Process(ResultOperatorBase resultOperator, QueryModelVisitor queryModel, IntermediateHqlTree tree);
public void Process(ClientSideSelect2 resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { tree.AddListTransformer(resultOperator.SelectClause); }
public void Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { tree.AddWhereClause(tree.TreeBuilder.BooleanNot( HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.Predicate, queryModelVisitor.VisitorParameters). ToBooleanExpression())); if (tree.IsRoot) { tree.AddTakeClause(tree.TreeBuilder.Constant(1)); Expression <Func <IEnumerable <object>, bool> > x = l => !l.Any(); tree.AddListTransformer(x); } else { tree.SetRoot(tree.TreeBuilder.BooleanNot(tree.TreeBuilder.Exists((HqlQuery)tree.Root))); } }
private void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree, HqlDot memberPath, IType propType) { string alias = null; if (resultOperator is FetchOneRequest) { if (propType == null) { var metadata = queryModelVisitor.VisitorParameters.SessionFactory .GetClassMetadata(resultOperator.RelationMember.ReflectedType); propType = metadata?.GetPropertyType(resultOperator.RelationMember.Name); } if (propType != null && !propType.IsAssociationType) { tree.AddFromLastChildClause(tree.TreeBuilder.Fetch()); tree.AddFromLastChildClause(memberPath); ComponentType componentType = null; foreach (var innerFetch in resultOperator.InnerFetchRequests) { if (componentType == null) { componentType = propType as ComponentType; if (componentType == null) { throw new InvalidOperationException( $"Property {innerFetch.RelationMember.Name} cannot be fetched from a non component type property {resultOperator.RelationMember.Name}."); } } var subTypeIndex = componentType.GetPropertyIndex(innerFetch.RelationMember.Name); memberPath = tree.TreeBuilder.Dot( memberPath, tree.TreeBuilder.Ident(innerFetch.RelationMember.Name)); Process(innerFetch, queryModelVisitor, tree, memberPath, componentType.Subtypes[subTypeIndex]); } return; } var relatedJoin = queryModelVisitor.RelatedJoinFetchRequests.FirstOrDefault(o => o.Value == resultOperator).Key; if (relatedJoin != null) { alias = queryModelVisitor.VisitorParameters.QuerySourceNamer.GetName(relatedJoin); } } if (alias == null) { alias = queryModelVisitor.Model.GetNewName("_"); tree.AddFromClause(tree.TreeBuilder.LeftFetchJoin(memberPath, tree.TreeBuilder.Alias(alias))); } tree.AddDistinctRootOperator(); foreach (var innerFetch in resultOperator.InnerFetchRequests) { Process(innerFetch, queryModelVisitor, tree, alias); } }
public void Process(AggregateResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var inputExpr = ((StreamedSequenceInfo)queryModelVisitor.PreviousEvaluationType).ItemExpression; var inputType = inputExpr.Type; var paramExpr = Expression.Parameter(inputType, "item"); var accumulatorFunc = Expression.Lambda( ReplacingExpressionVisitor.Replace(inputExpr, paramExpr, resultOperator.Func.Body), resultOperator.Func.Parameters[0], paramExpr); // NH-3850: changed from list transformer (working on IEnumerable<object>) to post execute // transformer (working on IEnumerable<inputType>) for globally aggregating polymorphic results // instead of aggregating results for each class separately and yielding only the first. // If the aggregation relies on ordering, final result will still be wrong due to // polymorphic results being union-ed without re-ordering. (This is a limitation of all polymorphic // queries, this is not specific to LINQ provider.) var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(inputType), "inputList"); var aggregate = ReflectionCache.EnumerableMethods.AggregateDefinition.MakeGenericMethod(inputType); MethodCallExpression call = Expression.Call( aggregate, inputList, accumulatorFunc ); tree.AddPostExecuteTransformer(Expression.Lambda(call, inputList)); // There is no more a list transformer yielding an IList<resultType>, but this aggregate case // have inputType = resultType, so no further action is required. }
public void Process(AllResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { tree.AddWhereClause(tree.TreeBuilder.BooleanNot( HqlGeneratorExpressionVisitor.Visit(resultOperator.Predicate, queryModelVisitor.VisitorParameters). ToBooleanExpression())); if (tree.IsRoot) { tree.AddTakeClause(tree.TreeBuilder.Constant(1)); Expression <Func <IEnumerable <object>, bool> > x = l => !l.Any(); tree.AddListTransformer(x); // NH-3850: Queries with polymorphism yields many results which must be combined. Expression <Func <IEnumerable <bool>, bool> > px = l => l.All(r => r); tree.AddPostExecuteTransformer(px); } else { tree.SetRoot(tree.TreeBuilder.BooleanNot(tree.TreeBuilder.Exists((HqlQuery)tree.Root))); } }
public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? ReflectionHelper.GetMethodDefinition(() => Queryable.FirstOrDefault <object>(null)) : ReflectionHelper.GetMethodDefinition(() => Queryable.First <object>(null)); AddClientSideEval(firstMethod, queryModelVisitor, tree); tree.AddTakeClause(tree.TreeBuilder.Constant(1)); }
public void Process(OptionResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { tree.AddAdditionalCriteria((q, p) => q.SetOption((string)resultOperator.Option.Value)); }
public void Process(NonAggregatingGroupBy resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var selector = queryModelVisitor.Model.SelectClause.Selector; var keySelector = resultOperator.GroupBy.KeySelector; var elementSelector = resultOperator.GroupBy.ElementSelector; var sourceType = selector.Type; var keyType = keySelector.Type; var elementType = elementSelector.Type; // Stuff in the group by that doesn't map to HQL. Run it client-side var listParameter = Expression.Parameter(typeof(IEnumerable <object>), "list"); var keySelectorExpr = ReverseResolvingExpressionVisitor.ReverseResolve(selector, keySelector); var elementSelectorExpr = ReverseResolvingExpressionVisitor.ReverseResolve(selector, elementSelector); var groupByMethod = ReflectionCache.EnumerableMethods.GroupByWithElementSelectorDefinition .MakeGenericMethod(new[] { sourceType, keyType, elementType }); var castToItem = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { sourceType }); var toList = ReflectionCache.EnumerableMethods.ToListDefinition.MakeGenericMethod(new[] { resultOperator.GroupBy.ItemType }); Expression castToItemExpr = Expression.Call(castToItem, listParameter); var groupByExpr = Expression.Call(groupByMethod, castToItemExpr, keySelectorExpr, elementSelectorExpr); var toListExpr = Expression.Call(toList, groupByExpr); var lambdaExpr = Expression.Lambda(toListExpr, listParameter); tree.AddListTransformer(lambdaExpr); }
public void Process(AggregateFromSeedResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var inputExpr = ((StreamedSequenceInfo)queryModelVisitor.PreviousEvaluationType).ItemExpression; var inputType = inputExpr.Type; var paramExpr = Expression.Parameter(inputType, "item"); var accumulatorFunc = Expression.Lambda( ReplacingExpressionTreeVisitor.Replace(inputExpr, paramExpr, resultOperator.Func.Body), resultOperator.Func.Parameters[0], paramExpr); var accumulatorType = resultOperator.Func.Parameters[0].Type; var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(typeof(object)), "inputList"); var castToItem = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { inputType }); var castToItemExpr = Expression.Call(castToItem, inputList); MethodCallExpression call; if (resultOperator.OptionalResultSelector == null) { var aggregate = ReflectionCache.EnumerableMethods.AggregateWithSeedDefinition .MakeGenericMethod(inputType, accumulatorType); call = Expression.Call( aggregate, castToItemExpr, resultOperator.Seed, accumulatorFunc ); } else { var selectorType = resultOperator.OptionalResultSelector.Type.GetGenericArguments()[2]; var aggregate = ReflectionCache.EnumerableMethods.AggregateWithSeedAndResultSelectorDefinition .MakeGenericMethod(inputType, accumulatorType, selectorType); call = Expression.Call( aggregate, castToItemExpr, resultOperator.Seed, accumulatorFunc, resultOperator.OptionalResultSelector ); } tree.AddListTransformer(Expression.Lambda(call, inputList)); }
public void Process(ResultOperatorBase resultOperator, QueryModelVisitor queryModel, IntermediateHqlTree tree) { ResultOperatorProcessorBase processor; if (_map.TryGetValue(resultOperator.GetType(), out processor)) { processor.Process(resultOperator, queryModel, tree); } else { throw new NotSupportedException(string.Format("The {0} result operator is not current supported", resultOperator.GetType().Name)); } }
public void Process(OfTypeResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { Expression source = queryModelVisitor.CurrentEvaluationType.As <StreamedSequenceInfo>().ItemExpression; tree.AddWhereClause(tree.TreeBuilder.Equality( tree.TreeBuilder.Dot( HqlGeneratorExpressionTreeVisitor.Visit(source, queryModelVisitor.VisitorParameters).AsExpression(), tree.TreeBuilder.Class()), tree.TreeBuilder.Ident(resultOperator.SearchedItemType.FullName))); }
public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? FirstOrDefault : First; AddClientSideEval(firstMethod, queryModelVisitor, tree); tree.AddTakeClause(tree.TreeBuilder.Constant(1)); }
public void Process(GroupResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { IEnumerable <Expression> groupByKeys; if (resultOperator.KeySelector is NewExpression) { groupByKeys = (resultOperator.KeySelector as NewExpression).Arguments; } else { groupByKeys = new[] { resultOperator.KeySelector } }; IEnumerable <HqlExpression> hqlGroupByKeys = groupByKeys.Select(k => HqlGeneratorExpressionTreeVisitor.Visit(k, queryModelVisitor.VisitorParameters).AsExpression()); tree.AddGroupByClause(tree.TreeBuilder.GroupBy(hqlGroupByKeys.ToArray())); } }
public void Process(FetchManyRequest resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { base.Process(resultOperator, queryModelVisitor, tree); }
public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { Process(tree); }
public void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree, string sourceAlias) { var join = tree.TreeBuilder.Dot( tree.TreeBuilder.Ident(sourceAlias), tree.TreeBuilder.Ident(resultOperator.RelationMember.Name)); string alias = queryModelVisitor.Model.GetNewName("_"); tree.AddFromClause(tree.TreeBuilder.LeftFetchJoin(join, tree.TreeBuilder.Alias(alias))); tree.AddDistinctRootOperator(); foreach (var innerFetch in resultOperator.InnerFetchRequests) { Process(innerFetch, queryModelVisitor, tree, alias); } }
public override void Process(ResultOperatorBase resultOperator, QueryModelVisitor queryModel, IntermediateHqlTree tree) { _processor.Process((T)resultOperator, queryModel, tree); }
public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)); }
public void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var querySource = QuerySourceLocator.FindQuerySource(queryModelVisitor.Model, resultOperator.RelationMember.DeclaringType); Process(resultOperator, queryModelVisitor, tree, querySource.ItemName); }
public void Process(CacheableResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { NamedParameter parameterName; switch (resultOperator.ParseInfo.ParsedExpression.Method.Name) { case "Cacheable": tree.AddAdditionalCriteria((q, p) => q.SetCacheable(true)); break; case "CacheMode": queryModelVisitor.VisitorParameters.ConstantToParameterMap.TryGetValue(resultOperator.Data, out parameterName); if (parameterName != null) { tree.AddAdditionalCriteria((q, p) => q.SetCacheMode((CacheMode)p[parameterName.Name].First)); } else { tree.AddAdditionalCriteria((q, p) => q.SetCacheMode((CacheMode)resultOperator.Data.Value)); } break; case "CacheRegion": queryModelVisitor.VisitorParameters.ConstantToParameterMap.TryGetValue(resultOperator.Data, out parameterName); if (parameterName != null) { tree.AddAdditionalCriteria((q, p) => q.SetCacheRegion((string)p[parameterName.Name].First)); } else { tree.AddAdditionalCriteria((q, p) => q.SetCacheRegion((string)resultOperator.Data.Value)); } break; } }
public void Process(NonAggregatingGroupBy resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var tSource = queryModelVisitor.Model.SelectClause.Selector.Type; var tKey = resultOperator.GroupBy.KeySelector.Type; var tElement = resultOperator.GroupBy.ElementSelector.Type; // Stuff in the group by that doesn't map to HQL. Run it client-side var listParameter = Expression.Parameter(typeof(IEnumerable <object>), "list"); ParameterExpression itemParam = Expression.Parameter(tSource, "item"); Expression keySelectorSource = itemParam; if (tSource != SourceOf(resultOperator.GroupBy.KeySelector)) { keySelectorSource = Expression.MakeMemberAccess(itemParam, tSource.GetMember( ((QuerySourceReferenceExpression) resultOperator.GroupBy.KeySelector).ReferencedQuerySource. ItemName)[0]); } Expression keySelector = new GroupByKeySelectorVisitor(keySelectorSource).Visit(resultOperator.GroupBy.KeySelector); Expression elementSelectorSource = itemParam; if (tSource != SourceOf(resultOperator.GroupBy.ElementSelector)) { elementSelectorSource = Expression.MakeMemberAccess(itemParam, tSource.GetMember( ((QuerySourceReferenceExpression) resultOperator.GroupBy.ElementSelector).ReferencedQuerySource. ItemName)[0]); } Expression elementSelector = new GroupByKeySelectorVisitor(elementSelectorSource).Visit(resultOperator.GroupBy.ElementSelector); var groupByMethod = EnumerableHelper.GetMethod("GroupBy", new[] { typeof(IEnumerable <>), typeof(Func <,>), typeof(Func <,>) }, new[] { tSource, tKey, tElement }); var castToItem = EnumerableHelper.GetMethod("Cast", new[] { typeof(IEnumerable) }, new[] { tSource }); var toList = EnumerableHelper.GetMethod("ToList", new[] { typeof(IEnumerable <>) }, new[] { resultOperator.GroupBy.ItemType }); LambdaExpression keySelectorExpr = Expression.Lambda(keySelector, itemParam); LambdaExpression elementSelectorExpr = Expression.Lambda(elementSelector, itemParam); Expression castToItemExpr = Expression.Call(castToItem, listParameter); var groupByExpr = Expression.Call(groupByMethod, castToItemExpr, keySelectorExpr, elementSelectorExpr); var toListExpr = Expression.Call(toList, groupByExpr); var lambdaExpr = Expression.Lambda(toListExpr, listParameter); tree.AddListTransformer(lambdaExpr); }
public void Process(SingleResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? SingleOrDefault : Single; AddClientSideEval(firstMethod, queryModelVisitor, tree); }
public void Process(ClientSideSelect resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { var inputType = resultOperator.SelectClause.Parameters[0].Type; var outputType = resultOperator.SelectClause.Type.GetGenericArguments()[1]; var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(inputType), "inputList"); var selectMethod = ReflectionCache.EnumerableMethods.SelectDefinition.MakeGenericMethod(new[] { inputType, outputType }); var toListMethod = ReflectionCache.EnumerableMethods.ToListDefinition.MakeGenericMethod(new[] { outputType }); var lambda = Expression.Lambda( Expression.Call(toListMethod, Expression.Call(selectMethod, inputList, resultOperator.SelectClause)), inputList); tree.AddListTransformer(lambda); }
public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { if (tree.IsRoot) { tree.AddTakeClause(tree.TreeBuilder.Constant(1)); Expression <Func <IEnumerable <object>, bool> > x = l => l.Any(); tree.AddListTransformer(x); } else { tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)); } }