protected Func <object, T> GetSelectProjector <T>(object firstResult, QueryModel queryModel) { Func <object, T> projector = (result) => result.Cast <T>(); if (ShouldBuildResultObjectMapping <T>(firstResult, queryModel)) { var proj = ProjectorBuildingExpressionTreeVisitor.BuildProjector <T>(queryModel.SelectClause.Selector); projector = (result) => proj(new ResultObjectMapping(queryModel.MainFromClause, result)); } return(projector); }
// Call this method to get the projector. T is the type of the result (after the projection). public static Func <ResultObjectMapping, T> BuildProjector <T>(Expression selectExpression) { // This is the parameter of the delegat we're building. It's the ResultObjectMapping, which holds all the input data needed for the projection. var resultItemParameter = Expression.Parameter(typeof(ResultObjectMapping), "resultItem"); // The visitor gives us the projector's body. It simply replaces all QuerySourceReferenceExpressions with calls to ResultObjectMapping.GetObject<T>(). var visitor = new ProjectorBuildingExpressionTreeVisitor(resultItemParameter); var body = visitor.Visit(selectExpression); // Construct a LambdaExpression from parameter and body and compile it into a delegate. var projector = Expression.Lambda <Func <ResultObjectMapping, T> >(body, resultItemParameter); return(projector.Compile()); }