Пример #1
0
        public JoinTableQueryPart(QueryIdentifier targetTable,
                                  QueryIdentifier sourceTable,
                                  QueryIdentifier joinAlias,
                                  Type targetTargetTableType,
                                  ColumnInfo targetColumn,
                                  ColumnInfo sourceColumn,
                                  IEnumerable <ColumnInfo> columns,
                                  DbPropertyInfoCache targetProperty,
                                  JoinMode joinAs)
        {
            _joinAs         = joinAs;
            TargetTable     = targetTable;
            SourceTable     = sourceTable;
            Alias           = joinAlias;
            TargetTableType = targetTargetTableType;
            Columns         = columns;

            TargetColumn   = targetColumn;
            SourceColumn   = sourceColumn;
            DependingJoins = new List <JoinTableQueryPart>();

            var joinInfos = new JoinParseInfo();

            joinInfos.TargetProperty   = targetProperty;
            joinInfos.Columns          = Columns;
            joinInfos.Alias            = Alias;
            joinInfos.SourceColumnName = SourceColumn;
            joinInfos.TargetColumnName = TargetColumn;

            joinInfos.SourceTable     = SourceTable;
            joinInfos.TargetTableType = targetTargetTableType;
            JoinParseInfo             = joinInfos;
        }
Пример #2
0
        public DeleteQuery <T> Delete <T>()
        {
            ContainerObject.Interceptors
            .Add(new EventPostProcessor(EventPostProcessor.EventType.Delete, ContainerObject.AccessLayer));
            var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(typeof(T));

            var targetAlias     = ContainerObject.CreateTableAlias(dbClassInfoCache.TableName);
            var queryIdentifier = new QueryIdentifier()
            {
                Value       = dbClassInfoCache.TableName,
                QueryIdType = QueryIdentifier.QueryIdTypes.Table
            };

            switch (ContainerObject.AccessLayer.DbAccessType)
            {
            case DbAccessType.Experimental:
            case DbAccessType.Unknown:
            case DbAccessType.OleDb:
            case DbAccessType.Obdc:
            case DbAccessType.SqLite:
                targetAlias.Value = queryIdentifier.Value;
                break;
            }

            return(new DeleteQuery <T>(
                       Add(new DeleteTableQueryPart(queryIdentifier,
                                                    targetAlias,
                                                    dbClassInfoCache,
                                                    ContainerObject,
                                                    UpdateTableWithQueryPart.ColumsOfType(dbClassInfoCache, targetAlias, queryIdentifier, ContainerObject)))));
        }
Пример #3
0
        public static IEnumerable <ColumnInfo> ColumsOfType(DbClassInfoCache dbClassInfoCache,
                                                            QueryIdentifier alias,
                                                            QueryIdentifier sourceReference,
                                                            IQueryContainer container)
        {
            return(DbAccessLayer.GetSelectableColumnsOf(dbClassInfoCache)
                   .Select(e =>
            {
                switch (container.AccessLayer.DbAccessType)
                {
                case DbAccessType.MsSql:
                case DbAccessType.MySql:
                    return new ColumnInfo(e, alias, container);

                case DbAccessType.Experimental:
                case DbAccessType.Unknown:
                case DbAccessType.OleDb:
                case DbAccessType.Obdc:
                case DbAccessType.SqLite:
                    return new ColumnInfo(e, sourceReference, null);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }).ToArray());
        }
Пример #4
0
        /// <summary>
        ///     Creates a Update statement for a given type
        /// </summary>
        /// <typeparam name="TPoco">The type of the poco.</typeparam>
        /// <returns></returns>
        public UpdateColumnSetters <TPoco> Table <TPoco>()
        {
            ContainerObject.Interceptors
            .Add(new EventPostProcessor(EventPostProcessor.EventType.Update, ContainerObject.AccessLayer));
            var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(typeof(TPoco));
            var targetAlias      = ContainerObject.CreateTableAlias(dbClassInfoCache.TableName);
            var queryIdentifier  = new QueryIdentifier()
            {
                Value       = dbClassInfoCache.TableName,
                QueryIdType = QueryIdentifier.QueryIdTypes.Table
            };

            if (ContainerObject.AccessLayer.DbAccessType.HasFlag(DbAccessType.Experimental) ||
                ContainerObject.AccessLayer.DbAccessType.HasFlag(DbAccessType.Unknown) ||
                ContainerObject.AccessLayer.DbAccessType.HasFlag(DbAccessType.OleDb) ||
                ContainerObject.AccessLayer.DbAccessType.HasFlag(DbAccessType.Obdc) ||
                ContainerObject.AccessLayer.DbAccessType.HasFlag(DbAccessType.SqLite))
            {
                targetAlias.Value = queryIdentifier.Value;
            }

            return(new UpdateColumnSetters <TPoco>(
                       Add(new UpdateTableWithQueryPart(
                               queryIdentifier,
                               UpdateTableWithQueryPart.ColumsOfType(dbClassInfoCache, targetAlias, queryIdentifier, ContainerObject),
                               targetAlias))));
        }
Пример #5
0
        public SelectTableQueryPart(ISelectableQueryPart source,
                                    DbClassInfoCache tableInfo,
                                    QueryIdentifier alias,
                                    IQueryContainer queryContainer)
        {
            _source    = source.Alias.GetAlias();
            _tableInfo = tableInfo;
            Alias      = alias;
            _columns   = new List <ColumnInfo>();
            _joins     = new List <JoinParseInfo>();

            _columns = source.Columns
                       .Select(e => new ColumnInfo(e.ColumnIdentifier().TrimAlias(), e, Alias, queryContainer)).ToList();

            if (source is CteDefinitionQueryPart.CteQueryPart cte)
            {
                queryContainer.Joins.Clear();
                var joinTableQueryParts = (cte.CteInfo.CteContentParts.FirstOrDefault(f => f is SelectTableQueryPart) as SelectTableQueryPart)
                                          ?.Joins;
                if (joinTableQueryParts != null)
                {
                    foreach (var joinTableQueryPart in joinTableQueryParts)
                    {
                        var cloneForJoinTo = joinTableQueryPart.CloneForJoinTo(Alias, _columns, source.Columns);
                        _joins.Add(cloneForJoinTo);
                        queryContainer.Joins.Add(cloneForJoinTo);
                    }
                }
            }
        }
Пример #6
0
 internal ColumnInfo(string columnName,
                     ColumnInfo aliasOf,
                     QueryIdentifier alias,
                     IQueryContainer container)
     : this(columnName, alias, container)
 {
     AliasOf = aliasOf;
 }
Пример #7
0
 public CountTargetQueryPart(QueryIdentifier queryId, QueryIdentifier alias)
 {
     Alias    = alias;
     _queryId = queryId;
     Columns  = new ColumnInfo[]
     {
         new ColumnInfo("[Source]", Alias, null),
     };
 }
Пример #8
0
 /// <summary>
 ///
 /// </summary>
 public ColumnInfo(string columnName,
                   QueryIdentifier sourceAlias,
                   IQueryContainer container)
 {
     Alias      = sourceAlias;
     _container = container;
     ColumnName = columnName;
     _counter   = container?.GetNextColumnId() ?? -1;
 }
Пример #9
0
        public SelectQuery <TPoco> SynteticColumn(string column, out QueryIdentifier identifier)
        {
            var selectableQueryPart = ContainerObject.SearchLast <SelectTableQueryPart>();
            var columnInfo          = new ColumnInfo(column, selectableQueryPart.Alias, ContainerObject);

            columnInfo.ColumnIdentifierEntry = ContainerObject.CreateColumnAlias(column);
            identifier = columnInfo.ColumnIdentifierEntry;
            selectableQueryPart._columns.Add(columnInfo);
            return(this);
        }
        /// <inheritdoc />
        public QueryIdentifier CreateAlias(QueryIdentifier.QueryIdTypes table)
        {
            var identifier = new QueryIdentifier();

            identifier.QueryIdType = table;
            identifier.Value       =
                $"[{identifier.QueryIdType.ToString()}_{Identifiers.Count(g => g.QueryIdType.Equals(identifier.QueryIdType))}]";
            Identifiers.Add(identifier);
            return(identifier);
        }
Пример #11
0
 public UpdateTableWithQueryPart(
     QueryIdentifier target,
     IEnumerable <ColumnInfo> targetsColumns,
     QueryIdentifier queryIdentifier)
 {
     Columns           = targetsColumns;
     _target           = target;
     Alias             = queryIdentifier;
     ColumnAssignments = new List <ColumnAssignment>();
 }
Пример #12
0
        /// <summary>
        ///		Selects all columns from the given Identifier
        /// </summary>
        /// <returns></returns>
        public SelectQuery <TPoco> Identifier <TPoco>(QueryIdentifier identifier)
        {
            ContainerObject.Interceptors.Add(new EventPostProcessor(EventPostProcessor.EventType.Select, ContainerObject.AccessLayer));
            var classInfo = ContainerObject.AccessLayer.GetClassInfo(typeof(TPoco));

            return(new SelectQuery <TPoco>(Add(new SelectTableQueryPart(
                                                   ContainerObject.Search(identifier),
                                                   classInfo,
                                                   ContainerObject.CreateTableAlias(classInfo.TableName), ContainerObject))));
        }
Пример #13
0
 public DeleteTableQueryPart(QueryIdentifier target,
                             QueryIdentifier alias,
                             DbClassInfoCache tableInfo,
                             IQueryContainer queryContainer,
                             IEnumerable <ColumnInfo> columns)
 {
     Alias    = alias;
     _columns = columns;
     _target  = target;
 }
Пример #14
0
 public SubSelectQueryPart(QueryIdentifier queryAlias,
                           IEnumerable <IQueryPart> subSelectionQueryParts,
                           IQueryContainer queryContainer)
 {
     Alias = queryAlias;
     SubSelectionQueryParts = subSelectionQueryParts;
     _columns = SubSelectionQueryParts
                .OfType <ISelectableQueryPart>()
                .LastOrDefault()?
                .Columns
                .Select(e => new ColumnInfo(e.ColumnIdentifier().TrimAlias(), e, Alias, queryContainer))
                .ToArray();
 }
Пример #15
0
 public JoinParseInfo CloneTo(QueryIdentifier @alias)
 {
     return(new JoinParseInfo()
     {
         TargetProperty = TargetProperty,
         Alias = @alias,
         Columns = Columns.Select(e => new ColumnInfo(e.ColumnName, @alias, e._container)).ToArray(),
         DependingJoins = DependingJoins.Select(e => e.CloneTo(@alias)).ToArray(),
         TargetTableType = TargetTableType,
         SourceTable = SourceTable,
         SourceColumnName = new ColumnInfo(SourceColumnName.ColumnName, SourceColumnName, alias, SourceColumnName._container),
         TargetColumnName = new ColumnInfo(TargetColumnName.ColumnName, TargetColumnName, alias, TargetColumnName._container)
     });
 }
Пример #16
0
        public SelectTableQueryPart(string source,
                                    DbClassInfoCache tableInfo,
                                    QueryIdentifier alias,
                                    IQueryContainer queryContainer)
        {
            _source    = source;
            _tableInfo = tableInfo;
            Alias      = alias;
            _columns   = new List <ColumnInfo>();
            _joins     = new List <JoinParseInfo>();

            _columns = DbAccessLayer.GetSelectableColumnsOf(_tableInfo)
                       .Select(e => new ColumnInfo(e, Alias, queryContainer))
                       .ToList();
        }
Пример #17
0
        /// <summary>
        ///		Creates a CTE on the start of the Query
        /// </summary>
        /// <returns></returns>
        public RootQuery WithCte <T>(IElementProducer <T> commandQuery, out QueryIdentifier cteName)
        {
            IQueryBuilder newQuery = new RootQuery(this);

            cteName = newQuery.ContainerObject.CreateAlias(QueryIdentifier.QueryIdTypes.Cte);
            (commandQuery.ContainerObject as IQueryContainerValues)?.TableAlias.Clear();

            var cteQueryPart = commandQuery.ContainerObject.SearchLast <CteDefinitionQueryPart>();

            newQuery = newQuery.Add(cteQueryPart ?? (cteQueryPart = new CteDefinitionQueryPart()));

            var cteInfo = new CteDefinitionQueryPart.CteInfo();

            cteInfo.Name = cteName;
            cteInfo.CteContentParts.AddRange(commandQuery.ContainerObject.Parts);
            return(new RootQuery(newQuery.Add(cteQueryPart.AddCte(cteInfo))));
        }
Пример #18
0
 public JoinParseInfo CloneForJoinTo(
     QueryIdentifier alias,
     IList <ColumnInfo> columnSource,
     IEnumerable <ColumnInfo> originalColumnSource)
 {
     return(new JoinParseInfo()
     {
         TargetProperty = TargetProperty,
         Alias = @alias,
         Columns = Columns.Select(e => columnSource.First(f => f.AliasOf.Equals(e))).ToArray(),
         DependingJoins = DependingJoins.Select(e => e.CloneForJoinTo(@alias, columnSource, originalColumnSource)).ToArray(),
         TargetTableType = TargetTableType,
         SourceTable = @alias,
         SourceColumnName = Columns.FirstOrDefault(f => f.AliasOf?.Equals(SourceColumnName) == true) ?? SourceColumnName,
         TargetColumnName = Columns.FirstOrDefault(f => f.AliasOf?.Equals(TargetColumnName) == true) ?? TargetColumnName
                            //SourceColumnName = SourceColumnName,
                            //TargetColumnName = TargetColumnName
     });
 }
Пример #19
0
 public static IEnumerable <ColumnInfo> ColumsOfType(DbClassInfoCache dbClassInfoCache,
                                                     QueryIdentifier alias,
                                                     QueryIdentifier sourceReference,
                                                     IQueryContainer container)
 {
     return(DbAccessLayer.GetSelectableColumnsOf(dbClassInfoCache)
            .Select(e =>
     {
         if (container.AccessLayer.DbAccessType.HasFlag(DbAccessType.MsSql) ||
             container.AccessLayer.DbAccessType.HasFlag(DbAccessType.MySql))
         {
             return new ColumnInfo(e, alias, container);
         }
         else
         {
             return new ColumnInfo(e, sourceReference, null);
         }
     }).ToArray());
 }
        private QueryIdentifier AddRangeIdentifier(SyntaxToken identifier)
        {
            string name = identifier.ValueText;

            if (name == LuaIdentifierNameSyntax.Placeholder.ValueText)
            {
                if (queryIdentifiers_.Exists(i => i.HasPack))
                {
                    name = kQueryPlaceholderConflictName;
                }
            }
            else
            {
                CheckLocalBadWord(ref name, identifier.Parent);
            }
            var queryIdentifier = new QueryIdentifier(identifier, new LuaIdentifierNameSyntax(name));

            queryIdentifiers_.Add(queryIdentifier);
            return(queryIdentifier);
        }
Пример #21
0
 public QueryCompositeFilter()
 {
     _filterList = new List <IQueryFilter>();
     _id         = QueryIdentifier.NewId();
 }
Пример #22
0
 /// <summary>
 ///		Creates a CTE on the start of the Query
 /// </summary>
 /// <returns></returns>
 public RootQuery WithCte <T>(IElementProducer <T> commandQuery, out QueryIdentifier cteName)
 {
     return(WithCte(commandQuery as IQueryBuilder, out cteName));
 }
Пример #23
0
 /// <summary>
 ///		Creates a CTE on the start of the Query
 /// </summary>
 /// <returns></returns>
 internal RootQuery WithCte(Func <RootQuery, IQueryBuilder> commandQueryProducer,
                            out QueryIdentifier cteName)
 {
     return(WithCte(commandQueryProducer(new RootQuery(this)), out cteName));
 }
 /// <inheritdoc />
 public ISelectableQueryPart Search(QueryIdentifier identifier)
 {
     return(Parts.OfType <ISelectableQueryPart>().First(e => e.Alias.Equals(identifier)));
 }
 /// <inheritdoc />
 public string GetPathOf(QueryIdentifier identifier)
 {
     return(TableAlias.FirstOrDefault(e => e.Value.Equals(identifier)).Key);
 }
Пример #26
0
 /// <summary>
 ///		Creates a CTE on the start of the Query
 /// </summary>
 /// <returns></returns>
 public RootQuery WithCte <T>(Func <RootQuery, IElementProducer <T> > commandQueryProducer,
                              out QueryIdentifier cteName)
 {
     return(WithCte(commandQueryProducer(new RootQuery(this)), out cteName));
 }
        private bool BuildQueryJoin(JoinClauseSyntax node, out LuaExpressionSyntax resultSelectorExpression, out LuaExpressionSyntax resultSelectorType, ref IQueryRangeVariable rangeVariable, QueryIdentifier queryIdentifier)
        {
            var parentNode = (QueryBodySyntax)node.Parent;

            if (IsSpecialQueryNode(parentNode))
            {
                var selectClause = (SelectClauseSyntax)parentNode.SelectOrGroup;
                resultSelectorExpression = (LuaExpressionSyntax)selectClause.Expression.Accept(this);
                var typeSymbol = semanticModel_.GetTypeInfo(selectClause.Expression).Type;
                resultSelectorType = GetTypeName(typeSymbol);
                return(true);
            }
            else
            {
                resultSelectorExpression = CreateQueryAnonymousType(rangeVariable.Name, rangeVariable.Name, queryIdentifier.Name, queryIdentifier.Name);
                resultSelectorType       = LuaIdentifierNameSyntax.AnonymousType;
                rangeVariable            = new QueryPackVariable(rangeVariable, queryIdentifier);
                return(false);
            }
        }
Пример #28
0
 public SynteticColumnInfo(string columnName,
                           QueryIdentifier sourceAlias,
                           IQueryContainer container)
     : base(columnName, sourceAlias, container)
 {
 }
Пример #29
0
        internal static SelectQuery <TPoco> JoinOn(
            IQueryBuilder builder,
            KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>[] path,
            JoinMode joinAs = null,
            Func <ConditionalEvalQuery <TPoco>, ConditionalEvalQuery <TPoco> > joinCondition = null)
        {
            joinAs = joinAs ?? JoinMode.Default;

            IQueryBuilder target      = builder;
            var           targetAlias = target.ContainerObject
                                        .SearchLast <ISelectableQueryPart>(e => !(e is JoinTableQueryPart))
                                        .Alias;
            var parentJoinPart = builder.ContainerObject.Joins;

            foreach (var keyValuePair in path)
            {
                var targetTable = target.ContainerObject.Search(targetAlias);

                var pathOfJoin = target.ContainerObject.GetPathOf(targetAlias) + "." +
                                 keyValuePair.Value.PropertyName;
                var parentAlias = target.ContainerObject
                                  .CreateTableAlias(pathOfJoin);

                var joinExists = parentJoinPart.FirstOrDefault(e => e.Alias.Equals(parentAlias));
                if (joinExists != null)
                {
                    parentJoinPart = joinExists.DependingJoins;
                    targetAlias    = parentAlias;
                    continue;
                }


                Type referenceType;
                if (keyValuePair.Value.CheckForListInterface())
                {
                    referenceType = keyValuePair.Value.PropertyType.GetElementType();
                    if (referenceType == null)
                    {
                        referenceType = keyValuePair.Value.PropertyType.GetGenericArguments().FirstOrDefault();
                    }
                }
                else
                {
                    referenceType = keyValuePair.Value.PropertyType;
                }

                var referencedTypeCache = target.ContainerObject.AccessLayer.GetClassInfo(referenceType);

                var targetAliasOfJoin = new QueryIdentifier
                {
                    QueryIdType = QueryIdentifier.QueryIdTypes.Table,
                    Value       = referencedTypeCache.TableName
                };

                ColumnInfo onSourceTableKey;
                ColumnInfo selfPrimaryKey;

                var referenceColumn = keyValuePair.Value.ForginKeyAttribute?.Attribute;

                if (referenceColumn == null)
                {
                    throw new InvalidOperationException("There is no known reference from table " +
                                                        $"'{keyValuePair.Key.Type}' " +
                                                        "to table " +
                                                        $"'{referenceType}'." +
                                                        "Use a ForeignKeyDeclarationAttribute to connect both");
                }

                var forginColumns = DbAccessLayer.GetSelectableColumnsOf(referencedTypeCache)
                                    .Select(e => new ColumnInfo(e, parentAlias, target.ContainerObject))
                                    .ToList();

                selfPrimaryKey
                    = targetTable.Columns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ForeignKey));
                onSourceTableKey
                    = forginColumns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ReferenceKey));

                var joinTableQueryPart = new JoinTableQueryPart(
                    targetAliasOfJoin,
                    targetAlias,
                    parentAlias,
                    keyValuePair.Key.Type,
                    onSourceTableKey,
                    selfPrimaryKey,
                    forginColumns,
                    keyValuePair.Value,
                    joinAs);

                parentJoinPart.Add(joinTableQueryPart.JoinParseInfo);
                parentJoinPart = joinTableQueryPart.JoinParseInfo.DependingJoins;

                target.ContainerObject.SearchLast <ISelectQueryPart>().AddJoin(joinTableQueryPart);
                target      = target.Add(joinTableQueryPart);
                targetAlias = parentAlias;
            }

            if (joinCondition != null)
            {
                var lastJoin   = target.ContainerObject.SearchLast <JoinTableQueryPart>();
                var condition  = new ConditionStatementQueryPart();
                var tempSelect = new ConditionalEvalQuery <TPoco>(target.Add(condition));
                joinCondition(tempSelect);
                lastJoin.Condition = condition;
            }

            return(new SelectQuery <TPoco>(target));
        }
Пример #30
0
        public EagarDataRecord[] DoJoinMapping(
            EagarDataRecord[] readers,
            QueryIdentifier sourceAlias,
            QueryProcessingRecordsContext context,
            bool sourceJoin = true,
            bool toplevel   = false)
        {
            foreach (var mapping in Mappings
                     .Where(e => sourceJoin ? e.SourceAlias.Equals(sourceAlias) : e.TargetAlias.Equals(sourceAlias)).ToArray())
            {
                var targetColumnsIndexMapping = new Dictionary <ColumnInfo, int>();
                var sourceColumnsIndexMapping = new Dictionary <ColumnInfo, int>();
                var targetColumns             = mapping.TargetColumns.ToArray();
                for (int index = 0; index < targetColumns.Length; index++)
                {
                    var columnInfo = targetColumns[index];

                    if (targetColumnsIndexMapping.ContainsKey(columnInfo))
                    {
                        throw new InvalidOperationException($"1Error while mapping columns. Column: '{columnInfo.NaturalName}' exists")
                              {
                                  Data = { { "Columns", targetColumnsIndexMapping } }
                              };
                    }

                    targetColumnsIndexMapping.Add(columnInfo, index);
                }

                var sourceColumns = mapping.SourceColumns.ToArray();
                for (int index = 0; index < sourceColumns.Length; index++)
                {
                    var columnInfo = sourceColumns[index];

                    if (sourceColumnsIndexMapping.ContainsKey(columnInfo))
                    {
                        throw new InvalidOperationException($"2Error while mapping columns. Column: '{columnInfo.NaturalName}' exists")
                              {
                                  Data = { { "Columns", sourceColumnsIndexMapping } }
                              };
                    }

                    sourceColumnsIndexMapping.Add(columnInfo, index);
                }
                var targetTable =
                    context.QueryContainer
                    .AccessLayer
                    .Config
                    .GetOrCreateClassInfoCache(mapping.TargetType);

                var primaryKeyColumn = mapping.SourceColumns.FirstOrDefault(e =>
                                                                            e.IsEquivalentTo(targetTable.PrimaryKeyProperty.DbName) &&
                                                                            e.Alias.Equals(mapping.TargetAlias));

                var primaryKeyOrdinal = sourceColumnsIndexMapping
                                        .FirstOrDefault(f => f.Key.IsEqualsTo(primaryKeyColumn));

                var targetOrdinal = sourceColumnsIndexMapping
                                    .FirstOrDefault(f => f.Key.IsEqualsTo(mapping.TargetColumn));

                var sourceOrdinal = targetColumnsIndexMapping
                                    .FirstOrDefault(f => f.Key.IsEqualsTo(mapping.SourceColumn));

                readers = readers
                          .GroupBy(e => e[primaryKeyOrdinal.Value])
                          .Select(e => e.First())
                          .Select(record =>
                {
                    SetRelationOnRecord(mapping.TargetName,
                                        mapping.Records,
                                        targetOrdinal.Value,
                                        record,
                                        sourceOrdinal.Value);
                    return(record);
                })
                          .ToArray();
                Mappings.Remove(mapping);
                DoJoinMapping(mapping.Records, mapping.SourceAlias, context, false);

                if (toplevel)
                {
                    context.Columns = context.Columns.Concat(new[]
                    {
                        new ColumnInfo(mapping.TargetName, null, null),
                    }).ToArray();
                }
            }
            return(readers);
        }