protected virtual EntityRecordReader CreateEntityReader(TableExpression tableExpression, TranslationContext context) { // Note: we have to create EntityRecordReader each time, because column indexes in output can change from query to query var reader = new EntityRecordReader(tableExpression.TableInfo); var allColExprs = RegisterAllColumns(tableExpression, context); foreach (var col in allColExprs) { var colIndex = RegisterOutputValue(col, context); reader.AddColumn(col.ColumnInfo, colIndex); } return(reader); }
public virtual void BuildSelectResultReaderAndCutOutSql(Expression forExpr, TranslationContext context, Type expectedResultType) { // collect columns, split Expression in // - things we will do in CLR // - things we will do in SQL LambdaExpression readerLambda; //do not try to get rid of this var; context.CurrentSelect can change by the end of the method EntityRecordReader entReader = null; var dataRecordParameter = Expression.Parameter(typeof(IDataRecord), "dataRecord"); var sessionParameter = Expression.Parameter(typeof(Entities.Runtime.EntitySession), "session"); // This is special optimization case for reading entities, to avoid Lambda.Compile, we use // instance of EntityRecordReader directly. DO NOT try to optimize or improve it!!! (talking to you, Roman) bool isSelectOp = context.Command.Operation == LinqOperation.Select; if (isSelectOp && forExpr is TableExpression tableExpr) { entReader = CreateEntityReader(tableExpr, context); readerLambda = null; } // if we have a GroupByExpression, the result type is not the same: // - we need to read what is going to be the Key expression // - the final row generator builds a IGrouping<K,T> instead of T else if (forExpr is GroupExpression groupExpression) { var sqlOutExpr = CutOutSqlTierLambda(groupExpression.GroupedExpression, dataRecordParameter, sessionParameter, null, context); var selectKeyExpr = CutOutSqlTierLambda(groupExpression.KeyExpression, dataRecordParameter, sessionParameter, null, context); readerLambda = sqlOutExpr; if (groupExpression.UseClrGrouping) { readerLambda = BuildGroupByPairsReader(sqlOutExpr, selectKeyExpr, dataRecordParameter, sessionParameter, context); var grouper = RowListProcessor.CreateGroupBy(selectKeyExpr.Body.Type, sqlOutExpr.Body.Type); context.CurrentSelect.RowListProcessor = grouper; context.CurrentSelect.Group.Remove(groupExpression); } } else { readerLambda = CutOutSqlTierLambda(forExpr, dataRecordParameter, sessionParameter, expectedResultType, context); } // wait until the end to assign these, CurrentSelect might have changed context.CurrentSelect.EntityReader = entReader; context.CurrentSelect.RowReaderLambda = readerLambda; }