将 DBNull 替换为 null
Replace DBNull with null
我目前正在开发一个使用 MS SQL-Server 的 C# WPF 项目。
由于使用 DBNull 值有点烦人,我想知道是否有可能以某种方式将它们转换为常规的 c# 空值。
我写了一个小包装器来连接到数据库,执行一个 SELECT 语句并且 return 结果作为一个 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、...)。
然后它将 return 给定类型的 Nullable
版本(例如 int?
对于 int
),如果值为 DBNull
.
,则为 null
- 第二种方法可用于值类型和对象类型。
在这里你还必须给出一个默认值,它将是 returned
当值是 DBNull
时。
此方法也可用于将 DBNull
更改为 null
,但仅适用于对象类型,因为它们始终可以设置为 null
和
不需要特殊说明 Nullable
.
扩展方法使您能够向现有类型添加方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但它们被调用时就好像它们是扩展类型的实例方法一样。
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
我目前正在开发一个使用 MS SQL-Server 的 C# WPF 项目。
由于使用 DBNull 值有点烦人,我想知道是否有可能以某种方式将它们转换为常规的 c# 空值。
我写了一个小包装器来连接到数据库,执行一个 SELECT 语句并且 return 结果作为一个 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、...)。然后它将 return 给定类型的
Nullable
版本(例如int?
对于int
),如果值为DBNull
. ,则为 - 第二种方法可用于值类型和对象类型。
在这里你还必须给出一个默认值,它将是 returned
当值是DBNull
时。 此方法也可用于将DBNull
更改为null
,但仅适用于对象类型,因为它们始终可以设置为null
和 不需要特殊说明Nullable
.
null
扩展方法使您能够向现有类型添加方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但它们被调用时就好像它们是扩展类型的实例方法一样。
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