/// <summary> /// Bind parameter expressions to <see cref="LambdaExpression"/>. /// </summary> /// <param name="lambdaExpression"><see cref="LambdaExpression"/> to bind parameters.</param> /// <param name="parameters"><see cref="Expression"/>s to bind to <paramref name="lambdaExpression"/></param> /// <returns>Body of <paramref name="lambdaExpression"/> with lambda's parameters replaced /// with corresponding expression from <paramref name="parameters"/></returns> /// <exception cref="InvalidOperationException">Something went wrong :(.</exception> public static Expression BindParameters(this LambdaExpression lambdaExpression, params Expression[] parameters) { if (lambdaExpression.Parameters.Count != parameters.Length) { throw new InvalidOperationException(String.Format( Strings.ExUnableToBindParametersToLambdaXParametersCountIsIncorrect, lambdaExpression.ToString(true))); } if (parameters.Length == 0) { return(lambdaExpression); } var convertedParameters = new Expression[parameters.Length]; for (int i = 0; i < lambdaExpression.Parameters.Count; i++) { var expressionParameter = lambdaExpression.Parameters[i]; if (expressionParameter.Type.IsAssignableFrom(parameters[i].Type)) { convertedParameters[i] = expressionParameter.Type == parameters[i].Type ? parameters[i] : Expression.Convert(parameters[i], expressionParameter.Type); } else { throw new InvalidOperationException(String.Format( Strings.ExUnableToUseExpressionXAsXParameterOfLambdaXBecauseOfTypeMistmatch, parameters[i].ToString(true), i, lambdaExpression.Parameters[i].ToString(true))); } } return(ExpressionReplacer.ReplaceAll( lambdaExpression.Body, lambdaExpression.Parameters, convertedParameters)); }
internal void Compile(params object[] args) { if (this.fnQuery == null) { // first identify the query provider being used Expression body = this.query.Body; ConstantExpression root = RootQueryableFinder.Find(body) as ConstantExpression; if (root == null && args != null && args.Length > 0) { Expression replaced = ExpressionReplacer.ReplaceAll( body, this.query.Parameters.ToArray(), args.Select((a, i) => Expression.Constant(a, this.query.Parameters[i].Type)).ToArray() ); body = PartialEvaluator.Eval(replaced); root = RootQueryableFinder.Find(body) as ConstantExpression; } if (root == null) { throw new InvalidOperationException("Could not find query provider"); } // ask the query provider to compile the query by 'executing' the lambda expression IQueryProvider provider = ((IQueryable)root.Value).Provider; Delegate result = (Delegate)provider.Execute(this.query); System.Threading.Interlocked.CompareExchange(ref this.fnQuery, result, null); } }
internal IQueryProvider FindProvider(Expression expression, object[] args) { Expression root = this.FindProviderInExpression(expression) as ConstantExpression; if (root == null && args != null && args.Length > 0) { Expression replaced = ExpressionReplacer.ReplaceAll( expression, this.query.Parameters.ToArray(), args.Select((a, i) => Expression.Constant(a, this.query.Parameters[i].Type)).ToArray() ); root = this.FindProviderInExpression(replaced); } if (root != null) { ConstantExpression cex = root as ConstantExpression; if (cex == null) { cex = PartialEvaluator.Eval(root) as ConstantExpression; } if (cex != null) { IQueryProvider provider = cex.Value as IQueryProvider; if (provider == null) { IQueryable query = cex.Value as IQueryable; if (query != null) { provider = query.Provider; } } return(provider); } } return(null); }