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);
        }
Beispiel #2
0
        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;
        }