/// <summary>
        /// Execute a command against a data source, mapping the data reader to an enumerable of record dictionaries.
        /// This method perfoms LAZY LOADING/DEFERRED EXECUTION.
        /// Note that THE DATA READER WILL NOT BE DISPOSED UPON ENUMERATION OR FOREACH BRANCH OUT.
        /// </summary>
        /// <param name="dbDataReader"> The target data reader. </param>
        /// <param name="recordsAffectedCallback"> Executed when the output count of records affected is available to return (post enumeration). </param>
        /// <returns> An enumerable of record dictionary instances, containing key/value pairs of data. </returns>
        public IEnumerable <IAdoNetStreamingRecord> GetRecordsFromReader(DbDataReader dbDataReader, Action <int> recordsAffectedCallback)
        {
            AdoNetStreamingRecord record;
            int    recordsAffected;
            long   recordIndex = 0;
            string key;
            object value;

            Guid _ = this.__enter();

            if ((object)dbDataReader == null)
            {
                throw new ArgumentNullException(nameof(dbDataReader));
            }

            //using (this.__use(_, dbDataReader))
            {
                this.__trace(_, "before yield loop");

                while (dbDataReader.Read())
                {
                    record = new AdoNetStreamingRecord(-1, recordIndex);

                    for (int fieldIndex = 0; fieldIndex < dbDataReader.FieldCount; fieldIndex++)
                    {
                        key   = dbDataReader.GetName(fieldIndex);
                        value = dbDataReader.GetValue(fieldIndex);
                        value = value.ChangeType <object>();

                        if (record.ContainsKey(key) || (key ?? string.Empty).Length == 0)
                        {
                            key = string.Format("Field_{0:0000}", fieldIndex);
                        }

                        record.Add(key, value);
                    }

                    this.__trace(_, "on yield item");

                    recordIndex++;
                    yield return(record);                    // LAZY PROCESSING INTENT HERE / DO NOT FORCE EAGER LOAD
                }

                this.__trace(_, "after yield loop");

                //this.__disp(_, dbDataReader);
            }

            recordsAffected = dbDataReader.RecordsAffected;

            if ((object)recordsAffectedCallback != null)
            {
                recordsAffectedCallback(recordsAffected);
            }

            this.__leave(_);
        }
        /// <summary>
        /// Execute a command against a data source, mapping the data reader GetSchemaTable() result to an enumerable of record dictionaries.
        /// This method perfoms LAZY LOADING/DEFERRED EXECUTION.
        /// Note that THE DATA READER WILL NOT BE DISPOSED UPON ENUMERATION OR FOREACH BRANCH OUT.
        /// </summary>
        /// <param name="dbDataReader"> The target data reader. </param>
        /// <param name="recordsAffectedCallback"> Executed when the output count of records affected is available to return (post enumeration). </param>
        /// <returns> An enumerable of record dictionary instances, containing key/value pairs of schema metadata. </returns>
        public IEnumerable <IAdoNetStreamingRecord> GetSchemaRecordsFromReader(DbDataReader dbDataReader, Action <int> recordsAffectedCallback)
        {
            ReadOnlyCollection <DbColumn> dbColumns;
            DbColumn dbColumn;

            PropertyInfo[]        propertyInfos;
            PropertyInfo          propertyInfo;
            AdoNetStreamingRecord record;
            int    recordsAffected;
            string key;
            object value;

            Guid _ = this.__enter();

            if ((object)dbDataReader == null)
            {
                throw new ArgumentNullException(nameof(dbDataReader));
            }

            if (!dbDataReader.CanGetColumnSchema())
            {
                throw new NotSupportedException(string.Format("The connection command type '{0}' does not support schema access.", dbDataReader.GetType().FullName));
            }

            //using (this.__use(_, dbDataReader))
            {
                dbColumns = dbDataReader.GetColumnSchema();

                this.__trace(_, "before yield loop");

                if ((object)dbColumns != null)
                {
                    for (long recordIndex = 0; recordIndex < dbColumns.Count; recordIndex++)
                    {
                        dbColumn = dbColumns[(int)recordIndex];

                        propertyInfos = dbColumn.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);

                        record = new AdoNetStreamingRecord(-1, recordIndex);

                        if ((object)propertyInfos != null)
                        {
                            for (int fieldIndex = 0; fieldIndex < propertyInfos.Length; fieldIndex++)
                            {
                                propertyInfo = propertyInfos[fieldIndex];

                                if (propertyInfo.GetIndexParameters().Any())
                                {
                                    continue;
                                }

                                key   = propertyInfo.Name;
                                value = propertyInfo.GetValue(dbColumn);
                                value = value.ChangeType <object>();

                                record.Add(key, value);
                            }
                        }

                        this.__trace(_, "on yield item");

                        yield return(record);                        // LAZY PROCESSING INTENT HERE / DO NOT FORCE EAGER LOAD
                    }
                }

                this.__trace(_, "after yield loop");

                //this.__disp(_, dbDataReader);
            }

            recordsAffected = dbDataReader.RecordsAffected;

            if ((object)recordsAffectedCallback != null)
            {
                recordsAffectedCallback(recordsAffected);
            }

            this.__leave(_);
        }