public override object Execute(Expression expression) { Logger.Log($"Executing expression '{expression}'. Strict: {strict}"); var parameterBuilder = new ParameterBuilder <TObject>(queryHelper, strict); //Validate that every tree node is supported var supportedTree = SupportedExpressionValidator.Validate(expression); //Replace variable and method references with their calculated values var evaluatedTree = PartialEvaluate(supportedTree); //Replace all expressions that correspond to LINQ methods with LinqExpression objects var linqTree = LinqQueryBuilder <TObject> .Parse(evaluatedTree, strict); //Merge sequential method calls together into a single statement (e.g. Where(A).Where(B) => Where(A && B)) var mergedTree = LinqQueryMerger.Parse(linqTree, strict); //Extract the Parameter details from each LinqExpression, replacing processed expressions with their TSource var legalTree = parameterBuilder.Build(mergedTree); //Construct the parameter objects required to execute all of the required requests var parameterSets = GetParameters(parameterBuilder); //Filter out server side only expressions so we don't execute them twice (such as Skip) var clientTree = ClientTreeBuilder.Parse(linqTree); //Convert the query to LINQ to Objects var enumerableTree = RewriteEnumerable(clientTree, parameterSets); var getResults = Expression.Lambda(enumerableTree).Compile(); if (getResults.Method.ReturnType.IsValueType) { try { return(getResults.DynamicInvoke()); } catch (TargetInvocationException ex) { throw ex.InnerException; } } return(((Func <object>)getResults)()); }
public static Expression ToClientExpression(this Expression expr) { return(ClientTreeBuilder.Parse(expr)); }