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