private TResult EvaluateLambda <TResult>(LinqLambdaExpression lambda, params QueryValue[] currentParameterValues)
            where TResult : QueryValue
        {
            ExceptionUtilities.Assert(lambda.Parameters.Count == currentParameterValues.Length, "LambdaExpression parameter count must match length of currentParameterValues");

            for (int i = 0; i < lambda.Parameters.Count; i++)
            {
                LinqParameterExpression lambdaParameter = lambda.Parameters[i];
                ExceptionUtilities.Assert(!this.lambdaParameterAssignments.ContainsKey(lambdaParameter), "Attempt to recursively evaluate lambda.");

                this.lambdaParameterAssignments[lambdaParameter] = currentParameterValues[i];
            }

            try
            {
                return((TResult)this.Evaluate(lambda.Body));
            }
            finally
            {
                foreach (var p in lambda.Parameters)
                {
                    this.lambdaParameterAssignments.Remove(p);
                }
            }
        }
            /// <summary>
            /// Visits a QueryExpression tree whose root node is the LinqLambdaExpression.
            /// </summary>
            /// <param name="expression">The root node of the expression tree being visited.</param>
            /// <returns>Uri query string representing the expression.</returns>
            public override string Visit(LinqLambdaExpression expression)
            {
                ExceptionUtilities.Assert(expression.Parameters.Count == 1, "Lambda only supported with exactly 1 parameter");
                var parameter = expression.Parameters.Single();

                int originalParameterCount = this.currentLambdaParameterNames.Count;

                try
                {
                    var parameterString = this.Convert(parameter);
                    var bodyString      = this.Convert(expression.Body);
                    if (string.IsNullOrEmpty(parameterString))
                    {
                        return(string.Format(CultureInfo.InvariantCulture, "{0}", bodyString));
                    }
                    else
                    {
                        return(string.Format(CultureInfo.InvariantCulture, "{0}:{1}", parameterString, bodyString));
                    }
                }
                finally
                {
                    this.currentLambdaParameterNames.Remove(parameter);
                    ExceptionUtilities.Assert(originalParameterCount == this.currentLambdaParameterNames.Count, "Current parameter count does not match");
                }
            }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqLambdaExpression expression)
        {
            var parameters = expression.Parameters.Select(this.ResolveTypes).Cast <LinqParameterExpression>().ToArray();
            var body       = this.ResolveTypes(expression.Body);
            var type       = new LinqLambdaType(body.ExpressionType, parameters.Select(p => p.ExpressionType), this.EvaluationStrategy);

            return(LinqBuilder.Lambda(body, parameters.ToArray(), type));
        }
        /// <summary>
        /// Helper method to rewrite lambda expressions with different parameter expressions
        /// </summary>
        /// <param name="newParameter">The parameter to use as a replacement</param>
        /// <param name="lambda">The lambda to rewrite</param>
        /// <returns>The rewritten lambda expression</returns>
        private QueryExpression RewriteLambda(LinqParameterExpression newParameter, LinqLambdaExpression lambda)
        {
            ExceptionUtilities.CheckArgumentNotNull(newParameter, "newParameter");
            ExceptionUtilities.CheckArgumentNotNull(lambda, "lambda");
            var oldParameter = lambda.Parameters.Single();

            return(new ParameterReplacingVisitor(oldParameter, newParameter).ReplaceExpression(lambda.Body));
        }
Exemple #5
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>Replaced expression.</returns>
        public virtual QueryExpression Visit(LinqLambdaExpression expression)
        {
            var             parameters = expression.Parameters.Select(this.ReplaceExpression).Cast <LinqParameterExpression>().ToArray();
            QueryExpression body       = this.ReplaceExpression(expression.Body);

            if (HasChanged(expression.Body, body) || HasChanged(expression.Parameters, parameters))
            {
                return(LinqBuilder.Lambda(body, parameters, expression.ExpressionType));
            }

            return(expression);
        }
 /// <summary>
 /// Initializes a new instance of the LinqJoinExpressionBase class.
 /// </summary>
 /// <param name="outer">First input collection.</param>
 /// <param name="inner">Second input collection.</param>
 /// <param name="outerKeySelector">First key selector to the join condition.</param>
 /// <param name="innerKeySelector">Second key selector to the join condition.</param>
 /// <param name="resultSelector">Result selector</param>
 /// <param name="type">The query type of the expression</param>
 protected LinqJoinExpressionBase(
     QueryExpression outer, 
     QueryExpression inner, 
     LinqLambdaExpression outerKeySelector, 
     LinqLambdaExpression innerKeySelector, 
     LinqLambdaExpression resultSelector, 
     QueryType type)
     : base(type)
 {
     this.Outer = outer;
     this.Inner = inner;
     this.OuterKeySelector = outerKeySelector;
     this.InnerKeySelector = innerKeySelector;
     this.ResultSelector = resultSelector;
 }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of the LinqJoinExpressionBase class.
 /// </summary>
 /// <param name="outer">First input collection.</param>
 /// <param name="inner">Second input collection.</param>
 /// <param name="outerKeySelector">First key selector to the join condition.</param>
 /// <param name="innerKeySelector">Second key selector to the join condition.</param>
 /// <param name="resultSelector">Result selector</param>
 /// <param name="type">The query type of the expression</param>
 protected LinqJoinExpressionBase(
     QueryExpression outer,
     QueryExpression inner,
     LinqLambdaExpression outerKeySelector,
     LinqLambdaExpression innerKeySelector,
     LinqLambdaExpression resultSelector,
     QueryType type)
     : base(type)
 {
     this.Outer            = outer;
     this.Inner            = inner;
     this.OuterKeySelector = outerKeySelector;
     this.InnerKeySelector = innerKeySelector;
     this.ResultSelector   = resultSelector;
 }
Exemple #8
0
        /// <summary>
        /// Evaluates the given lambda as if it were called on the given entity. Used for evaluating orderby expressions for the last result in a feed.
        /// </summary>
        /// <param name="entity">The entity to evaluate the lambda for.</param>
        /// <param name="lamda">The lamda to evaluate.</param>
        /// <returns>The result of evaluating the lamda for the given entity.</returns>
        private object EvaluateLambdaForEntity(QueryStructuralValue entity, LinqLambdaExpression lamda)
        {
            var expression = CommonQueryBuilder.Root("fakeSet", entity.Type.CreateCollectionType()).Select(lamda).Single();

            var fakeQueryDataSet = new QueryDataSet();

            fakeQueryDataSet.RootQueryData["fakeSet"] = entity.Type.CreateCollectionType().CreateCollectionWithValues(new[] { entity });

            QueryValue evaluated;

            using (this.ExpressionEvaluator.WithTemporaryDataSet(fakeQueryDataSet))
            {
                evaluated = this.ExpressionEvaluator.Evaluate(expression);
            }

            return(((QueryScalarValue)evaluated).Value);
        }
        private QueryValue EvaluateQueryMethodWithLambdaExpression <TResult>(
            LinqQueryMethodWithLambdaExpression expression,
            Func <QueryCollectionValue, QueryValue> nolambdaEvaluator,
            Func <QueryCollectionValue, Func <QueryValue, TResult>, QueryValue> lambdaEvaluator)
            where TResult : QueryValue
        {
            var source = this.EvaluateCollection(expression.Source);

            LinqLambdaExpression lambda = expression.Lambda;

            if (lambda == null)
            {
                ExceptionUtilities.Assert(nolambdaEvaluator != null, "noLambdaEvaluator must not be null.");
                return(nolambdaEvaluator(source));
            }
            else
            {
                return(lambdaEvaluator(source, v => this.EvaluateLambda <TResult>(lambda, v)));
            }
        }
        private LinqLambdaExpression ResolveLambdaTypes(LinqLambdaExpression lambda, params QueryCollectionType[] parameterCollectionTypes)
        {
            ExceptionUtilities.Assert(lambda.Parameters.Count == parameterCollectionTypes.Length, "Lambda expression parameter numbers must match the length of parameterCollectionTypes.");

            for (int i = 0; i < lambda.Parameters.Count; i++)
            {
                var lambdaParameter = lambda.Parameters[i];
                this.parameterMappings.Add(lambdaParameter, LinqBuilder.Parameter(lambdaParameter.Name, parameterCollectionTypes[i].ElementType));
            }

            try
            {
                return((LinqLambdaExpression)this.ResolveTypes(lambda));
            }
            finally
            {
                foreach (var p in lambda.Parameters)
                {
                    this.parameterMappings.Remove(p);
                }
            }
        }
 internal LinqToAstoriaExpandLambdaExpression(QueryExpression source, LinqLambdaExpression expandLambdaExpression, QueryType type)
     : base(source, type)
 {
     this.Lambda = expandLambdaExpression;
 }
        /// <summary>
        /// Evaluates the given lambda as if it were called on the given entity. Used for evaluating orderby expressions for the last result in a feed.
        /// </summary>
        /// <param name="entity">The entity to evaluate the lambda for.</param>
        /// <param name="lamda">The lamda to evaluate.</param>
        /// <returns>The result of evaluating the lamda for the given entity.</returns>
        private object EvaluateLambdaForEntity(QueryStructuralValue entity, LinqLambdaExpression lamda)
        {
            var expression = CommonQueryBuilder.Root("fakeSet", entity.Type.CreateCollectionType()).Select(lamda).Single();

            var fakeQueryDataSet = new QueryDataSet();
            fakeQueryDataSet.RootQueryData["fakeSet"] = entity.Type.CreateCollectionType().CreateCollectionWithValues(new[] { entity });

            QueryValue evaluated;
            using (this.ExpressionEvaluator.WithTemporaryDataSet(fakeQueryDataSet))
            {
                evaluated = this.ExpressionEvaluator.Evaluate(expression);
            }

            return ((QueryScalarValue)evaluated).Value;
        }
Exemple #13
0
 /// <summary>
 /// Initializes a new instance of the LinqQueryMethodWithLambdaExpression class.
 /// </summary>
 /// <param name="source">The source expression.</param>
 /// <param name="lambda">The lambda expression.</param>
 /// <param name="type">The type of expression.</param>
 protected LinqQueryMethodWithLambdaExpression(QueryExpression source, LinqLambdaExpression lambda, QueryType type)
     : base(source, type)
 {
     this.Lambda = lambda;
 }
        /// <summary>
        /// Factory method to create the <see cref="LinqToAstoriaExpandLambdaExpression"/>.
        /// </summary>
        /// <param name="source">The source query.</param>
        /// <param name="expandValues">The expand lambda expression.</param>
        /// <returns>The <see cref="QueryExpression"/> with the provided arguments.</returns>
        public static QueryExpression Expand(this QueryExpression source, LinqLambdaExpression expandValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(source, "source");

            return new LinqToAstoriaExpandLambdaExpression(source, expandValues, QueryType.Unresolved);
        }
Exemple #15
0
 /// <summary>
 /// Visits a QueryExpression tree whose root node is the LinqLambdaExpression.
 /// </summary>
 /// <param name="expression">The root node of the expression tree being visited.</param>
 /// <returns>Uri query string representing the expression.</returns>
 public virtual string Visit(LinqLambdaExpression expression)
 {
     throw new TaupoNotSupportedException("Not supported");
 }
 /// <summary>
 /// Initializes a new instance of the LinqQueryMethodWithLambdaExpression class.
 /// </summary>
 /// <param name="source">The source expression.</param>
 /// <param name="lambda">The lambda expression.</param>
 /// <param name="type">The type of expression.</param>
 protected LinqQueryMethodWithLambdaExpression(QueryExpression source, LinqLambdaExpression lambda, QueryType type)
     : base(source, type)
 {
     this.Lambda = lambda;
 }
Exemple #17
0
        /// <summary>
        /// Generates System.CodeDom.CodeExpression from the given expression.
        /// </summary>
        /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param>
        /// <returns>Generated System.CodeDom.CodeExpression.</returns>
        public virtual CodeExpression Visit(LinqLambdaExpression expression)
        {
            CodeExpression body = this.GenerateCode(expression.Body);

            return(Code.Lambda().WithBody(body).WithParameters(expression.Parameters.Select(p => p.Name).ToArray()));
        }
 private QueryCollectionValue EvaluateKeysForJoin(QueryCollectionValue inputCollection, LinqLambdaExpression keySelector)
 {
     return(inputCollection.Select(e => this.EvaluateLambda <QueryValue>(keySelector, e)));
 }
        private QueryCollectionValue RewriteGroupingElements(QueryCollectionValue groupings, LinqLambdaExpression elementSelectorLambda)
        {
            var groupingElementType   = (QueryGroupingType)groupings.Type.ElementType;
            var rewrittenGroupingType = new QueryGroupingType(groupingElementType.Key.PropertyType, elementSelectorLambda.Body.ExpressionType, groupingElementType.EvaluationStrategy);

            var rewrittenGroupings = new List <QueryValue>();

            foreach (var grouping in groupings.Elements.Cast <QueryStructuralValue>())
            {
                QueryCollectionValue elements = grouping.GetCollectionValue("Elements");
                var rewrittenElements         = elements.Select(e => this.EvaluateLambda <QueryValue>(elementSelectorLambda, e));
                var rewrittenGrouping         = rewrittenGroupingType.CreateNewInstance();
                rewrittenGrouping.SetValue("Key", grouping.GetValue("Key"));
                rewrittenGrouping.SetValue("Elements", rewrittenElements);
                rewrittenGroupings.Add(rewrittenGrouping);
            }

            var result = rewrittenGroupingType.CreateCollectionType().CreateCollectionWithValues(rewrittenGroupings);

            return(result);
        }
Exemple #20
0
        /// <summary>
        /// Factory method to create the <see cref="LinqToAstoriaExpandLambdaExpression"/>.
        /// </summary>
        /// <param name="source">The source query.</param>
        /// <param name="expandValues">The expand lambda expression.</param>
        /// <returns>The <see cref="QueryExpression"/> with the provided arguments.</returns>
        public static QueryExpression Expand(this QueryExpression source, LinqLambdaExpression expandValues)
        {
            ExceptionUtilities.CheckArgumentNotNull(source, "source");

            return(new LinqToAstoriaExpandLambdaExpression(source, expandValues, QueryType.Unresolved));
        }
 /// <summary>
 /// Helper method to rewrite lambda expressions with different parameter expressions
 /// </summary>
 /// <param name="newParameter">The parameter to use as a replacement</param>
 /// <param name="lambda">The lambda to rewrite</param>
 /// <returns>The rewritten lambda expression</returns>
 private QueryExpression RewriteLambda(LinqParameterExpression newParameter, LinqLambdaExpression lambda)
 {
     ExceptionUtilities.CheckArgumentNotNull(newParameter, "newParameter");
     ExceptionUtilities.CheckArgumentNotNull(lambda, "lambda");
     var oldParameter = lambda.Parameters.Single();
     return new ParameterReplacingVisitor(oldParameter, newParameter).ReplaceExpression(lambda.Body);
 }
 /// <summary>
 /// Evaluates the specified expression.
 /// </summary>
 /// <param name="expression">The expression to evaluate.</param>
 /// <returns>Value of the expression.</returns>
 public QueryValue Visit(LinqLambdaExpression expression)
 {
     throw new TaupoNotSupportedException("Lambdas cannot be evaluated directly, but only through query operators that use them.");
 }
            /// <summary>
            /// Visits a QueryExpression tree whose root node is the LinqLambdaExpression.
            /// </summary>
            /// <param name="expression">The root node of the expression tree being visited.</param>
            /// <returns>Uri query string representing the expression.</returns>
            public override string Visit(LinqLambdaExpression expression)
            {
                ExceptionUtilities.Assert(expression.Parameters.Count == 1, "Lambda only supported with exactly 1 parameter");
                var parameter = expression.Parameters.Single();

                int originalParameterCount = this.currentLambdaParameterNames.Count;
                try
                {
                    var parameterString = this.Convert(parameter);
                    var bodyString = this.Convert(expression.Body);
                    if (string.IsNullOrEmpty(parameterString))
                    {
                        return string.Format(CultureInfo.InvariantCulture, "{0}", bodyString);
                    }
                    else
                    {
                        return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", parameterString, bodyString);
                    }
                }
                finally
                {
                    this.currentLambdaParameterNames.Remove(parameter);
                    ExceptionUtilities.Assert(originalParameterCount == this.currentLambdaParameterNames.Count, "Current parameter count does not match");
                }
            }
 private Func <object, QueryScalarValue> CreateKeySelector(LinqLambdaExpression keySelectorLambda)
 {
     return(e => this.EvaluateLambda <QueryScalarValue>(keySelectorLambda, e as QueryValue));
 }