// Executes the expression tree that is passed to it.
        public object Execute(Expression expression, bool isEnumerable)
        {
            // The expression must represent a query over the data source.
            if (!IsQueryOverDataSource(expression))
            {
                throw new InvalidProgramException("No query over the data source was specified.");
            }

            string whereClause = "";

            // Find the call to Where() and get the lambda expression predicate.
            var whereExpression = new InnermostWhereFinder().GetInnermostWhere(expression);

            if (whereExpression != null)
            {
                var lambdaExpression = (LambdaExpression)((UnaryExpression)whereExpression.Arguments[1]).Operand;

                // Send the lambda expression through the partial evaluator.
                lambdaExpression = (LambdaExpression)Evaluator.PartialEval(lambdaExpression);

                var builder = new FSWhereBuilder(lambdaExpression.Body);

                whereClause = builder.WhereClause;
            }

            var queryableResult = _fsRep.Get(whereClause).AsQueryable();

            return(isEnumerable
                ? queryableResult.Provider.CreateQuery(expression)
                : queryableResult.Provider.Execute(expression));
        }
예제 #2
0
        /// <summary>
        ///     Executes the given <paramref name="queryModel" /> as a collection query, i.e. as a query returning objects of type
        ///     <typeparamref name="T" />.
        ///     The query does not end with a scalar result operator, but it can end with a single result operator, for example
        ///     <see cref="T:Remotion.Linq.Clauses.ResultOperators.SingleResultOperator" /> or
        ///     <see cref="T:Remotion.Linq.Clauses.ResultOperators.FirstResultOperator" />. In such a case, the returned enumerable
        ///     must yield exactly
        ///     one object (or none if the last result operator allows empty result sets).
        /// </summary>
        /// <typeparam name="T">The type of the items returned by the query.</typeparam>
        /// <typeparam name="TFSEntity"></typeparam>
        /// <param name="queryModel">
        ///     The <see cref="T:Remotion.Linq.QueryModel" /> representing the query to be executed. Analyze this via an
        ///     <see cref="T:Remotion.Linq.IQueryModelVisitor" />.
        /// </param>
        /// <returns>A scalar value of type <typeparamref name="TFSEntity" /> that represents the query's result.</returns>
        public IEnumerable <T> ExecuteCollection <T>(QueryModel queryModel)
        {
            var command = FSQueryModelVisitor.GenerateFSQuery(queryModel);

            if (_command != null)
            {
                var whereClause = command.WhereClause.HasValue() && _command.WhereClause.HasValue()
                    ? command.WhereClause + " AND " + _command.WhereClause
                                        : command.WhereClause.HasValue()
                        ? command.WhereClause
                                            : _command.WhereClause.HasValue()
                            ? _command.WhereClause
                                                : string.Empty;

                var orderBy = _command.OrderByClause.HasValue()
                    ? string.Join(",", _command.OrderByClause, command.OrderByClause).Trim(',')
                    : command.OrderByClause;

                command = new FSCommand(
                    whereClause: whereClause,
                    orderByClause: orderBy,
                    offset: command.Offset ?? _command.Offset,
                    limit: command.Limit ?? _command.Limit
                    );
            }

            var fsQuery = _rep.Get(command.WhereClause, command.OrderByClause, command.Offset, command.Limit);

            var projection = FSProjectionVisitor <TFSEntity, T> .BuildProjector(queryModel.SelectClause.Selector);

            return(fsQuery.Select(projection));
        }