Заменить DBNull на ноль - PullRequest
       16

Заменить DBNull на ноль

0 голосов
/ 21 ноября 2018

В настоящее время я работаю над C # WPF-проектом, использующим MS SQL-сервер.

Поскольку работа со значениями DBNull несколько раздражает, я подумал, можно ли как-то преобразовать их в обычный c #пустые значения.

Я написал небольшую оболочку для подключения к базе данных, выполнил инструкцию SELECT и вернул результат в виде DataTable:

public static DataTable getResultTable(string select, params DbParameter[] parameters) {
    using (OleDbConnection connection = new OleDbConnection(_connectionString)) {
        connection.Open();
        try {
            using (OleDbCommand cmd = new OleDbCommand(select, connection)) {
                for (int i = 0; i < parameters.Length; i++) {
                    cmd.Parameters.Add("?", parameters[i].type).Value = parameters[i].value;
                }
                using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd)) {
                    using (DataTable dt = new DataTable()) {
                        adapter.Fill(dt);

                        //Here my DataTable dt is filled with the required data
                        //I´d like to replace all DBNull Values with regular null values now

                        return dt;
                    }
                }
            }
        } finally {
            connection.Close();
        }
    }
}

Я уверен, что мог бы зацикливаться на каждом полеDataTable и замените значение в случае, если это DBNull, но мне интересно, есть ли лучший способ.

РЕДАКТИРОВАТЬ:

Для всех, кто сталкивался с этим вопросом.Используя ответ @Sergiu Muresan, я создал два метода расширения, которые точно соответствуют моим потребностям:

public static class ExtensionMethods {
    public static T? GetValue<T>(this DataRow row, string columnName) where T : struct {
        if (row[columnName] is T)
            return (T)row[columnName];
        return null;
    }

    public static T GetValue<T>(this DataRow row, string columnName, T defaultValue) {
        return (row[columnName] is T) ? (T)row[columnName] : defaultValue;
    }
}
  • Первый метод ограничивает T-Patameter только struct, что означаетВы можете использовать здесь только значения-типы (int, bool, double, ...), но не используйте типы объектов (string, customObjects, ...).

    Затем вернется версия Nullableданного типа (например, int? для int), который будет null, если значение было DBNull.

  • Второй метод может использоваться как для типов-значений, так и для объекта-типы.Здесь также необходимо указать значение по умолчанию, которое будет возвращено
    , если значение DBNull.Этот метод также можно использовать для изменения DBNull на null, но только для типов объектов, так как они всегда могут быть установлены на null и не требуют указания Nullable.

1 Ответ

0 голосов
/ 21 ноября 2018

Методы расширения позволяют добавлять методы к существующим типам без создания нового производного типа, перекомпиляции или иного изменения исходного типа.Метод расширения - это особый вид статического метода, но он вызывается так, как если бы он был методом экземпляра для расширенного типа.

public static class ExtensionMethods
{
    public static T GetValue<T>(this DataRow row, string columnName, T defaultValue = default(T))
    {
        var obj = row[columnName];

        // if obj is DbNull it will skip this and return the default value
        if (obj is T)
        {
            return (T)obj;
        }

        return defaultValue;
    }
}

И вы можете использовать его следующим образом:

var dt = getResultTable(...);

var value1 = dt.Rows[0].GetValue<int>("ColumnName");

var value2 = dt.Rows[0].GetValue<int>("ColumnName", 10); // you can also specify a different default value if needed
...