MySQLDataReader, извлекающий проблему с нулевым значением в C#

В настоящее время я работаю над проектом C#, который будет экспортировать данные MySQL. Экспорт для любой базы данных на сервере, поэтому я не буду знать, какие поля и типы данных находятся в таблице, и я не буду знать, допускает ли поле в таблице нулевые значения или нет.

Во время тестирования я обнаружил, что экспорт работает нормально, но если поле допускает пустое значение, когда средство чтения данных mysql попадает в пустую строку, это отображает ошибку SqlNullValueException, данные равны нулю.

Я пытался делать if (reader.getString(field) == null) {} но это все еще показывает ошибку.

Как мне справиться со значениями Null в базе данных.

Спасибо за любую помощь, которую вы можете предоставить.

7 ответов

Решение

Вам нужно явно проверить на null в считывателе так:

if (!reader.IsDbNull(field)) {
    var value = reader.GetString(field);
    // ... do stuff here ...
}

В этом посте есть хороший метод расширения для читателя.

SQL Data Reader - обработка нулевых значений столбца

Я изменил его на интерфейс IDataReader

public static string GetStringSafe(this IDataReader reader, int colIndex)
    {
        return GetStringSafe(reader, colIndex, string.Empty);
    }

    public static string GetStringSafe(this IDataReader reader, int colIndex, string defaultValue)
    {
        if (!reader.IsDBNull(colIndex))
            return reader.GetString(colIndex);
        else
            return defaultValue;
    }

    public static string GetStringSafe(this IDataReader reader, string indexName)
    {
        return GetStringSafe(reader, reader.GetOrdinal(indexName));
    }

    public static string GetStringSafe(this IDataReader reader, string indexName, string defaultValue)
    {
        return GetStringSafe(reader, reader.GetOrdinal(indexName), defaultValue);
    }

.Net не использует null буквально различать базы данных нулями. Я могу только строить догадки, но я подозреваю, что причина этого в том, что многие распространенные типы столбцов базы данных (int, float и т. Д.) Являются типами значений, и сравнение типа значений с нулем не будет работать вообще, как вы ожидаете.

Вместо этого проверьте DBNull.Value или используйте .IsDbNull() функция.

Вы всегда можете использовать условный оператор C# '?' вот так...

string val = (reader.IsDBNull(columnIndex)) ? "" : reader.GetString(columnIndex);

У меня были проблемы с использованием метода GetString() для полей, которые допускают нулевые значения. Я работал над этим, делая что-то вроде:

reader[0].ToString()

Вы можете сравнить объект, который извлекается из поля NULL, с DBNull.Value.

Расширение ответа @Summer-Time для включения столбцов int:

      using System.Data;

namespace MyApp
{

    public static class AppExtensions
    {
        public static string GetStringSafe(this IDataReader reader, int colIndex)
        {
            return GetStringSafe(reader, colIndex, string.Empty);
        }

        public static string GetIntAsStringSafe(this IDataReader reader, int colIndex, string defaultValue)
        {
            if (!reader.IsDBNull(colIndex))
                return reader.GetInt32(colIndex).ToString();
            else
                return defaultValue;
        }

        public static string GetIntAsStringSafe(this IDataReader reader, int colIndex)
        {
           return GetIntAsStringSafe(reader, colIndex, string.Empty);
        }


        public static string GetStringSafe(this IDataReader reader, int colIndex, string defaultValue)
        {
            if (!reader.IsDBNull(colIndex))
                return reader.GetString(colIndex);
            else
                return defaultValue;
        }

        public static string GetStringSafe(this IDataReader reader, string indexName)
        {
            return GetStringSafe(reader, reader.GetOrdinal(indexName));
        }

        public static string GetStringSafe(this IDataReader reader, string indexName, string defaultValue)
        {
            return GetStringSafe(reader, reader.GetOrdinal(indexName), defaultValue);
        }
    }
}
Другие вопросы по тегам