Exemple #1
0
        public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            var convertExpression  = Expression.Convert(inputParameter, SearchedItemType);
            var expressionWithCast = ReplacingExpressionTreeVisitor.Replace(inputParameter, convertExpression, expressionToBeResolved);

            return(Source.Resolve(inputParameter, expressionWithCast, clauseGenerationContext));
        }
        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(
                ReplacingExpressionTreeVisitor.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(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(
                ReplacingExpressionTreeVisitor.Replace(inputExpr, paramExpr, resultOperator.Func.Body),
                resultOperator.Func.Parameters[0],
                paramExpr);

            var inputList = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(typeof(object)), "inputList");

            var castToItem     = ReflectionCache.EnumerableMethods.CastDefinition.MakeGenericMethod(new[] { inputType });
            var castToItemExpr = Expression.Call(castToItem, inputList);

            var aggregate = ReflectionCache.EnumerableMethods.AggregateDefinition.MakeGenericMethod(inputType);

            MethodCallExpression call = Expression.Call(
                aggregate,
                castToItemExpr,
                accumulatorFunc
                );

            tree.AddListTransformer(Expression.Lambda(call, inputList));
        }
        public void VisitUnknownNonExtensionExpression_Ignored()
        {
            var expression = new UnknownExpression(typeof(object));
            var result     = ReplacingExpressionTreeVisitor.Replace(_replacedNode, _replacementNode, expression);

            Assert.That(result, Is.SameAs(expression));
        }
Exemple #5
0
        public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            // we modify the structure of the stream of data coming into this node by our result selector,
            // so we first resolve the result selector, then we substitute the result for the inputParameter in the expressionToBeResolved
            var resolvedResultSelector = GetResolvedResultSelector(clauseGenerationContext);

            return(ReplacingExpressionTreeVisitor.Replace(inputParameter, resolvedResultSelector, expressionToBeResolved));
        }
        public void IgnoresTree_WhenReplacedNodeDoesNotExist()
        {
            var tree = ExpressionHelper.CreateLambdaExpression();

            var result = ReplacingExpressionTreeVisitor.Replace(_replacedNode, _replacementNode, tree);

            Assert.That(result, Is.SameAs(tree));
        }
        public void ReplacesGivenNode_ByGivenReplacement()
        {
            var tree = _replacedNode;

            var result = ReplacingExpressionTreeVisitor.Replace(_replacedNode, _replacementNode, tree);

            Assert.That(result, Is.SameAs(_replacementNode));
        }
        public override Expression Resolve(
            ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            Utils.CheckNotNull("inputParameter", inputParameter);
            Utils.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            var resolvedSelector = GetResolvedAdaptedSelector(clauseGenerationContext);

            return(ReplacingExpressionTreeVisitor.Replace(inputParameter, resolvedSelector, expressionToBeResolved));
        }
        public void VisitExtensionExpression_DescendsIntoChildren()
        {
            var tree = new VBStringComparisonExpression(_replacedNode, true);

            var result = ReplacingExpressionTreeVisitor.Replace(_replacedNode, _replacementNode, tree);

            var expected = new VBStringComparisonExpression(_replacementNode, true);

            ExpressionTreeComparer.CheckAreEqualTrees(expected, result);
        }
        public void ReplacesTreePart()
        {
            var tree = Expression.MakeBinary(ExpressionType.Add, Expression.Constant(0), _replacedNode);

            var result = ReplacingExpressionTreeVisitor.Replace(_replacedNode, _replacementNode, tree);

            var expectedResult = Expression.MakeBinary(ExpressionType.Add, Expression.Constant(0), _replacementNode);

            ExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result);
        }
        private static IQueryable <T> CreateQuery <T, TR>(
            IQueryable <T> source, Expression <Func <IQueryable <T>, TR> > expression)
        {
            var newQueryExpression = ReplacingExpressionTreeVisitor.Replace(
                expression.Parameters[0],
                source.Expression,
                expression.Body);

            return(source.Provider.CreateQuery <T>(newQueryExpression));
        }
Exemple #12
0
        public override Expression Resolve(
            ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            ArgumentUtility.CheckNotNull("inputParameter", inputParameter);
            ArgumentUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            var convertExpression  = Expression.Convert(inputParameter, CastItemType);
            var expressionWithCast = ReplacingExpressionTreeVisitor.Replace(inputParameter, convertExpression, expressionToBeResolved);

            return(Source.Resolve(inputParameter, expressionWithCast, clauseGenerationContext));
        }
Exemple #13
0
        /// <summary>
        /// Replaces the given parameter with a back-reference to the <see cref="IQuerySource"/> corresponding to <paramref name="referencedNode"/>.
        /// </summary>
        /// <param name="referencedNode">The referenced node.</param>
        /// <param name="parameterToReplace">The parameter to replace with a <see cref="QuerySourceReferenceExpression"/>.</param>
        /// <param name="expression">The expression in which to replace the parameter.</param>
        /// <param name="context">The clause generation context.</param>
        /// <returns><paramref name="expression"/>, with <paramref name="parameterToReplace"/> replaced with a <see cref="QuerySourceReferenceExpression"/>
        /// pointing to the clause corresponding to <paramref name="referencedNode"/>.</returns>
        public static Expression ReplaceParameterWithReference(
            IQuerySourceExpressionNode referencedNode,
            ParameterExpression parameterToReplace,
            Expression expression,
            ClauseGenerationContext context)
        {
            var clause = GetQuerySourceForNode(referencedNode, context);
            var referenceExpression = new QuerySourceReferenceExpression(clause);

            return(ReplacingExpressionTreeVisitor.Replace(parameterToReplace, referenceExpression, expression));
        }
Exemple #14
0
        public static Expression Resolve <TParameter, TResult> (
            IQuerySource sourceToReference,
            Expression <Func <TParameter, TResult> > expressionToBeResolved)
        {
            ArgumentUtility.CheckNotNull("sourceToReference", sourceToReference);
            ArgumentUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            return(ReplacingExpressionTreeVisitor.Replace(
                       expressionToBeResolved.Parameters[0],
                       new QuerySourceReferenceExpression(sourceToReference),
                       expressionToBeResolved.Body));
        }
        public void ReplacesTreePart_InSubQueries()
        {
            var replacedNode    = ExpressionHelper.CreateQueryable <Cook> ().Expression;
            var replacementNode = Expression.Constant(null, typeof(Cook[]));

            var subQueryMainFromClause = new MainFromClause("c", typeof(Cook), replacedNode);
            var subQuery = ExpressionHelper.CreateQueryModel(subQueryMainFromClause);

            var tree = new SubQueryExpression(subQuery);

            ReplacingExpressionTreeVisitor.Replace(replacedNode, replacementNode, tree);

            Assert.That(subQueryMainFromClause.FromExpression, Is.SameAs(replacementNode));
        }
Exemple #16
0
        /// <summary>
        /// Replaces the given parameter with a back-reference to the <see cref="IQuerySource"/> corresponding to <paramref name="referencedNode"/>.
        /// </summary>
        /// <param name="referencedNode">The referenced node.</param>
        /// <param name="parameterToReplace">The parameter to replace with a <see cref="QuerySourceReferenceExpression"/>.</param>
        /// <param name="expression">The expression in which to replace the parameter.</param>
        /// <param name="context">The clause generation context.</param>
        /// <returns><paramref name="expression"/>, with <paramref name="parameterToReplace"/> replaced with a <see cref="QuerySourceReferenceExpression"/>
        /// pointing to the clause corresponding to <paramref name="referencedNode"/>.</returns>
        public static Expression ReplaceParameterWithReference(
            IQuerySourceExpressionNode referencedNode,
            ParameterExpression parameterToReplace,
            Expression expression,
            ClauseGenerationContext context)
        {
            ArgumentUtility.CheckNotNull("referencedNode", referencedNode);
            ArgumentUtility.CheckNotNull("parameterToReplace", parameterToReplace);
            ArgumentUtility.CheckNotNull("expression", expression);
            ArgumentUtility.CheckNotNull("context", context);

            var clause = GetQuerySourceForNode(referencedNode, context);
            var referenceExpression = new QuerySourceReferenceExpression(clause);

            return(ReplacingExpressionTreeVisitor.Replace(parameterToReplace, referenceExpression, expression));
        }
Exemple #17
0
        public void SetUp()
        {
            _querySource      = ExpressionHelper.CreateMainFromClause_Int();
            _sourceExpression = new QuerySourceReferenceExpression(_querySource);

            var originalFunc = ExpressionHelper.CreateLambdaExpression <int, int, int> ((total, i) => total + i);

            _func = Expression.Lambda(
                ReplacingExpressionTreeVisitor.Replace(originalFunc.Parameters[1], _sourceExpression, originalFunc.Body),
                originalFunc.Parameters[0]);
            _resultSelector = ExpressionHelper.CreateLambdaExpression <int, string> (total => total.ToString());

            _seed = Expression.Constant(12);
            _resultOperatorWithoutResultSelector = new AggregateFromSeedResultOperator(_seed, _func, null);
            _resultOperatorWithResultSelector    = new AggregateFromSeedResultOperator(_seed, _func, _resultSelector);
        }
Exemple #18
0
        /// <summary>
        /// Wraps the query in a deferred <see cref="IFutureValue{T}"/> which will trigger a batch of all pending future queries
        /// when its <see cref="IFutureValue{T}.Value"/> is read.
        /// </summary>
        /// <param name="source">An <see cref="T:System.Linq.IQueryable`1" /> to convert to a future query.</param>
        /// <param name="selector">An aggregation function to apply to <paramref name="source"/>.</param>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
        /// <typeparam name="TResult">The type of the value returned by the function represented by <paramref name="selector"/>.</typeparam>
        /// <returns>A <see cref="IFutureValue{T}"/>.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
        /// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
        public static IFutureValue <TResult> ToFutureValue <TSource, TResult>(this IQueryable <TSource> source, Expression <Func <IQueryable <TSource>, TResult> > selector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (!(source.Provider is INhQueryProvider provider))
            {
                throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
            }

            var expression = ReplacingExpressionTreeVisitor
                             .Replace(selector.Parameters.Single(), source.Expression, selector.Body);

            return(provider.ExecuteFutureValue <TResult>(expression));
        }
Exemple #19
0
        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 static IFutureValue <TResult> ToFutureValue <T, TResult>(this IQueryable <T> query, Expression <Func <IQueryable <T>, TResult> > selector)
        {
            var nhQueryable = query as QueryableBase <T>;

            if (nhQueryable == null)
            {
                throw new NotSupportedException("Query needs to be of type QueryableBase<T>");
            }

            var provider = (INhQueryProvider)query.Provider;

            var expression = ReplacingExpressionTreeVisitor.Replace(selector.Parameters.Single(),
                                                                    query.Expression,
                                                                    selector.Body);

            return((IFutureValue <TResult>)provider.ExecuteFuture(expression));
        }
Exemple #21
0
        public override Expression Resolve(
            ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            Utils.CheckNotNull("inputParameter", inputParameter);
            Utils.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            if (IsLetNode)
            {
                // We modify the structure of the stream of data coming into this node by our selector,
                // so we first resolve the selector (adapted to include a reference to the let clause), then we substitute the result for the inputParameter
                // in the expressionToBeResolved.
                var resolvedSelector = GetResolvedAdaptedSelector(clauseGenerationContext);
                return(ReplacingExpressionTreeVisitor.Replace(inputParameter, resolvedSelector, expressionToBeResolved));
            }

            return(base.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext));
        }
Exemple #22
0
        private Expression CreateAggregate(Expression fromClauseExpression, LambdaExpression body, Func <Expression, Expression> aggregateFactory, Func <ResultOperatorBase> resultOperatorFactory)
        {
            var fromClause   = new MainFromClause(_nameGenerator.GetNewName(), body.Parameters[0].Type, fromClauseExpression);
            var selectClause = body.Body;

            selectClause = ReplacingExpressionTreeVisitor.Replace(body.Parameters[0],
                                                                  new QuerySourceReferenceExpression(
                                                                      fromClause), selectClause);
            var queryModel = new QueryModel(fromClause,
                                            new SelectClause(aggregateFactory(selectClause)));

            // TODO - this sucks, but we use it to get the Type of the SubQueryExpression correct
            queryModel.ResultOperators.Add(resultOperatorFactory());

            var subQuery = new SubQueryExpression(queryModel);

            queryModel.ResultOperators.Clear();

            return(subQuery);
        }
Exemple #23
0
        public static Expression ResolveLambdaParameter <TParameter1, TParameter2, TResult> (
            int parameterToResolveIndex,
            IQuerySource source,
            Expression <Func <TParameter1, TParameter2, TResult> > expressionToBeResolved)
        {
            ArgumentUtility.CheckNotNull("source", source);
            ArgumentUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            var parameterToResolve = expressionToBeResolved.Parameters[parameterToResolveIndex];

            var resolvedBody = ReplacingExpressionTreeVisitor.Replace(
                parameterToResolve,
                new QuerySourceReferenceExpression(source),
                expressionToBeResolved.Body);

            var remainingParameters = new List <ParameterExpression> (expressionToBeResolved.Parameters);

            remainingParameters.Remove(parameterToResolve);

            return(Expression.Lambda(resolvedBody, remainingParameters.ToArray()));
        }
Exemple #24
0
 // Takes a queryable and a transformation of that queryable and returns an expression representing that transformation,
 // This is required to get an expression with a result operator such as Count or First.
 // Use as follows:
 // var query = from ... select ...;
 // var countExpression = MakeExpression (query, q => q.Count());
 private Expression MakeExpression <TSource, TResult> (IQueryable <TSource> queryable, Expression <Func <IQueryable <TSource>, TResult> > func)
 {
     return(ReplacingExpressionTreeVisitor.Replace(func.Parameters[0], queryable.Expression, func.Body));
 }
 private LambdaExpression CreateFunc <TA1, TA2, TR> (Expression <Func <TA1, TA2, TR> > originalFunc)
 {
     return(Expression.Lambda(
                ReplacingExpressionTreeVisitor.Replace(originalFunc.Parameters[1], _sourceExpression, originalFunc.Body),
                originalFunc.Parameters[0]));
 }