/// <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));
        }
Пример #2
0
 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);
     }
 }
Пример #3
0
            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);
            }