将DBNull替换为null

时间:2018-11-21 14:42:52

标签: c# sql sql-server dbnull

我目前正在研究使用MS SQL Server的C#WPF项目。

由于使用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参数限制为struct,即 表示您只能在此处使用值类型(int,bool,double,...),但是 没有对象类型(字符串,customObjects等)。

    然后它将返回给定类型的Nullable版本(例如int? int),如果值为null,则为DBNull

  • 第二种方法可以用于值类型和对象类型。 在这里,您还必须提供默认值,该值将被返回
    当vlaue为DBNull时。       此方法也可以用于将DBNull更改为null,但仅适用于对象类型,因为它们始终可以设置为null并 不需要特殊的Nullable

1 个答案:

答案 0 :(得分:2)

扩展方法使您可以将方法添加到现有类型,而无需创建新的派生类型,重新编译或修改原始类型。扩展方法是一种特殊的静态方法,但它们的调用就像是扩展类型上的实例方法一样。

def tc(d):
  return d.assign(Total=d.drop('Total', errors='ignore', axis=1).sum(1))

df.pipe(tc).T.pipe(tc).T

              Graduate  Undergraduate  Total
Not                440           3760   4200
Straight A's        60            240    300
Total              500           4000   4500

您可以像这样使用它

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;
    }
}