private static IDataFieldReader CreateDataFieldReader(IDataRecord dataRecord, FoundationDbColumn dataColumnSchema)
    {
        var columnOrdinal = dataColumnSchema.ColumnOrdinal;
        var providerType  = (SqlDbType)dataColumnSchema.ProviderType;
        IDataFieldReader dataFieldReader;

        switch (providerType)
        {
        case SqlDbType.BigInt:
        case SqlDbType.Bit:
        case SqlDbType.Udt:
        case SqlDbType.Int:
        case SqlDbType.SmallInt:
        case SqlDbType.TinyInt:
        case SqlDbType.UniqueIdentifier:
        case SqlDbType.Real:     //
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Float:     //
            dataFieldReader = new DoubleFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Char:
        case SqlDbType.NChar:
        case SqlDbType.VarChar:
        case SqlDbType.NVarChar:
        case SqlDbType.Text:
        case SqlDbType.NText:
            var columnSize = dataColumnSchema.ColumnSize;

            if (columnSize <= SqlServerProvider.ShortStringSize)
            {
                dataFieldReader = new ShortStringFieldReader(dataRecord, columnOrdinal, providerType);
            }
            else
            {
                dataFieldReader = new LongStringFieldReader(dataRecord, columnOrdinal);
            }

            break;

        case SqlDbType.Binary:
        case SqlDbType.VarBinary:
        case SqlDbType.Image:
        case SqlDbType.Timestamp:
            dataFieldReader = new BinaryDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Decimal:
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.SmallDateTime:
            dataFieldReader = new SmallDateTimeDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Date:
        case SqlDbType.DateTime:
        case SqlDbType.DateTime2:
            dataFieldReader = new DateTimeDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.DateTimeOffset:
            dataFieldReader = new DateTimeOffsetDataFieldReader(dataRecord, columnOrdinal);
            break;


        case SqlDbType.Time:
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Money:
            dataFieldReader = new MoneyDataFieldReader(dataRecord, columnOrdinal);
            break;

        case SqlDbType.Variant:
            dataFieldReader = new VariantDataFieldReader(dataRecord, columnOrdinal);
            break;

        //                case SqlDbType.Timestamp:
        //                    dataFieldReader = new TimeStampDataFieldReader(dataRecord,columnOrdinal);
        //                    break;

        case SqlDbType.Xml:
            dataFieldReader = new LongStringFieldReader(dataRecord, columnOrdinal);
            break;

        default:
            throw new Exception();
        }

        return(dataFieldReader);
    }
    static IDataFieldReader CreateDataFieldReader(
        IDataRecord dataRecord,
        DataRow schemaRow)
    {
        var oracleDataReader = (OracleDataReader)dataRecord;
        var columnOrdinal    = (int)schemaRow["ColumnOrdinal"];
        var providerType     = (OracleDbType)schemaRow["ProviderType"];
        IDataFieldReader dataFieldReader;

        switch (providerType)
        {
        case OracleDbType.Blob:
        case OracleDbType.Char:
        case OracleDbType.Byte:
        case OracleDbType.Double:
        case OracleDbType.Int16:
        case OracleDbType.Int32:
        case OracleDbType.Int64:
        case OracleDbType.Long:
        case OracleDbType.NVarchar2:
        case OracleDbType.Varchar2:
        case OracleDbType.IntervalDS:
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        case OracleDbType.TimeStamp:
            dataFieldReader = new OracleTimestampFieldReader(oracleDataReader, columnOrdinal);
            break;

        case OracleDbType.TimeStampTZ:
            dataFieldReader = new OracleTimestampTzFieldReader(oracleDataReader, columnOrdinal);
            break;

        case OracleDbType.TimeStampLTZ:
            dataFieldReader = new OracleTimestampLtzFieldReader(oracleDataReader, columnOrdinal);
            break;

        case OracleDbType.Clob:
        case OracleDbType.NClob:
            dataFieldReader = new LongStringFieldReader(dataRecord, columnOrdinal);
            break;

        case OracleDbType.Date:
            dataFieldReader = new DateTimeDataFieldReader(oracleDataReader, columnOrdinal);
            break;

        case OracleDbType.Decimal:
            dataFieldReader = new OracleNumberDataFieldReader(oracleDataReader, columnOrdinal);
            break;

        case OracleDbType.Single:
            dataFieldReader = new SingleFieldDataReader(dataRecord, columnOrdinal);
            break;

        case OracleDbType.Raw:
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        case OracleDbType.XmlType:
            dataFieldReader = new DefaultDataFieldReader(dataRecord, columnOrdinal);
            break;

        default:
            throw new Exception();
        }

        return(dataFieldReader);
    }