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)); }
/// <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; }
/// <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; }
/// <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); }
/// <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> /// 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); }
/// <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)); }