public static Func <ResultObjectMapping, Func <T, T> > BuildAggregateProjector(QueryModel model, LambdaExpression aggregate)
        {
            var visitor = new ProjectorBuildingExpressionTreeVisitor <T>(aggregate, model.MainFromClause.ItemType);
            var body    = visitor.VisitExpression(aggregate);

            return(Expression.Lambda <Func <ResultObjectMapping, Func <T, T> > >(body, visitor.ResultItemParameter).Compile());
        }
        // Call this method to get the projector. T is the type of the result (after the projection).
        public static Func <ResultObjectMapping, T> BuildProjector(QueryModel model)
        {
            // The visitor gives us the projector's body. It simply replaces all QuerySourceReferenceExpressions with calls to ResultObjectMapping.GetObject<T>().
            var  selector           = model.SelectClause.Selector;
            Type resultTypeOverride = null;
            var  castOperator       = model.ResultOperators.LastOrDefault(it => it is CastResultOperator) as CastResultOperator;

            if (castOperator != null && selector.Type != castOperator.CastItemType)
            {
                resultTypeOverride = castOperator.CastItemType;
            }
            var allOperator = model.ResultOperators.LastOrDefault(it => it is AllResultOperator) as AllResultOperator;

            if (allOperator != null)
            {
                resultTypeOverride = allOperator.Predicate.Type;
            }
            if (model.ResultOperators.Any(it => it is CountResultOperator))
            {
                resultTypeOverride = typeof(int);
            }
            if (model.ResultOperators.Any(it => it is LongCountResultOperator))
            {
                resultTypeOverride = typeof(long);
            }
            if (model.ResultOperators.Any(it => it is AnyResultOperator))
            {
                resultTypeOverride = typeof(bool);
            }

            var visitor = new ProjectorBuildingExpressionTreeVisitor <T>(selector, resultTypeOverride);
            var body    = visitor.VisitExpression(selector);

            // Construct a LambdaExpression from parameter and body and compile it into a delegate.
            return(Expression.Lambda <Func <ResultObjectMapping, T> >(body, visitor.ResultItemParameter).Compile());
        }
 public GenericProjection(QueryModel model)
 {
     Func = ProjectorBuildingExpressionTreeVisitor <TOut> .BuildProjector(model);
 }