internal static List <string> Gather(Expression ex) { ColumnNamedGatherer gatherer = new ColumnNamedGatherer(); gatherer.Visit(ex); return(gatherer.columnNames); }
// end mike private Expression ExecuteProjection(ProjectionExpression projection, bool okayToDefer) { okayToDefer &= (receivingMember != null && policy.IsDeferLoaded(receivingMember)); // parameterize query projection = (ProjectionExpression)policy.Mapping.Language.Parameterize(projection); if (scope != null) { // also convert references to outer alias to named values! these become SQL parameters too projection = (ProjectionExpression)OuterParameterizer.Parameterize(scope.Alias, projection); } var saveScope = scope; ParameterExpression reader = Expression.Parameter(typeof(DbDataReader), "r" + nReaders++); scope = new Scope(scope, reader, projection.Source.Alias, projection.Source.Columns); LambdaExpression projector = Expression.Lambda(Visit(projection.Projector), reader); scope = saveScope; List <string> columnNames = ColumnNamedGatherer.Gather(projector.Body); //mike string commandText = policy.Mapping.Language.Format(projection.Source); var namedValues = NamedValueGatherer.Gather(projection.Source); var names = namedValues.Select(v => v.Name).ToArray(); Expression[] values = namedValues.Select(v => Expression.Convert( v.ParameterBindingAction != null ? v.ParameterBindingAction((ConstantExpression)v.Value) : Visit(v.Value), typeof(object))).ToArray(); string methExecute = okayToDefer ? "ExecuteDeferred" : "Execute"; if (okayToDefer) { } // call low-level execute directly on supplied DbQueryProvider Expression result = Expression.Call(provider, methExecute, new[] { projector.Body.Type }, Expression.New( typeof(QueryCommand <>).MakeGenericType(projector.Body.Type). GetConstructors()[0], Expression.Constant(commandText), Expression.Constant(names), projector, Expression.Constant(columnNames) ), Expression.NewArrayInit(typeof(object), values) ); if (projection.Aggregator != null) { // apply aggregator result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result); } return(result); }