当前位置:  开发笔记 > 编程语言 > 正文

处理DBNull的最佳方法是什么?

如何解决《处理DBNull的最佳方法是什么?》经验,为你挑选了5个好方法。

我经常遇到处理DataRows退回的问题SqlDataAdapters.当我尝试使用如下代码填充对象时:

DataRow row = ds.Tables[0].Rows[0];
string value = (string)row;

DBNull's在这种情况下处理这种情况的最佳方法是什么.



1> Dan Herbert..:

可空类型很好,但仅适用于开头不可为空的类型.

要使类型"可为空",请在类型中附加问号,例如:

int? value = 5;

我还建议使用" as"关键字而不是强制转换.您只能在可空类型上使用"as"关键字,因此请确保您正在构建已经可以为空的内容(如字符串),或者使用如上所述的可空类型.对此的推理是

    如果类型可以为空,则如果值为,则as返回" "关键字.nullDBNull

    尽管只是在某些情况下,它比铸造速度快得多.这本身就没有足够的理由使用,但加上上面的原因它很有用.as

我建议做这样的事情

DataRow row = ds.Tables[0].Rows[0];
string value = row as string;

在上面的情况下,如果row回来DBNull,那么value将变为null而不是抛出异常.请注意,如果您的数据库查询更改了要返回的列/类型,则使用as将导致代码无提示失败并使值变得简单,null而不是在返回不正确的数据时抛出相应的异常,因此建议您进行适当的测试以验证您的查询以其他方式确保您的代码库发展时的数据完整性.



2> Daniel Auger..:

如果您没有使用可空类型,最好的办法是检查列的值是否为DBNull.如果是DBNull,则将引用设置为对于相应数据类型使用null/empty的引用.

DataRow row = ds.Tables[0].Rows[0];
string value;

if (row["fooColumn"] == DBNull.Value)
{
   value = string.Empty;
}
else 
{
   value = Convert.ToString(row["fooColumn"]);
}

正如Manu所说,你可以创建一个转换类,每个类型都有一个重载的转换方法,所以你不必用if/else块来代码.

但是我会强调,如果可以使用可空类型,那么它们是更好的选择.原因在于,对于非可空类型,您将不得不求助于"魔术数字"来表示null.例如,如果要将列映射到int变量,那么您将如何表示DBNull?通常你不能使用0,因为0在大多数程序中都有有效含义.我经常看到人们将DBNull映射到int.MinValue,但这也可能存在问题.我最好的建议是:

对于数据库中可以为null的列,请使用可空类型.

对于数据库中不能为null的列,请使用常规类型.

可以使用可空类型来解决这个问题.话虽这么说,如果您使用的是较旧版本的框架,或者为那些没有grok nullable类型的人工作,那么代码示例就可以解决问题.


如果你想把dbnull视为空字符串行["fooColumn"].ToString()会这样做.

3> Keith..:

添加System.Data.DataSetExtensions对该查询的引用,增加了Linq对查询数据表的支持.

这将是这样的:

string value = (
    from row in ds.Tables[0].Rows
    select row.Field(0) ).FirstOrDefault();


+1:这个答案应该更加赞成并且可能也被接受 - 肯定是row.Field ("column_name")是处理null(DBNull.Value)的最有效,可读和干净的解决方案.还有row.SetField ("column_name",value)用于将值写入行.

4> Meff..:

我总是使用If/Else检查版本,只有三元运算符才能清楚,简洁,无问题.将所有内容保留在一行中,包括如果列为空则指定默认值.

因此,假设名为"MyCol"的可为空的Int32列,如果列为null,则返回-99,但如果列不为null,则返回整数值:

return row["MyCol"] == DBNull.Value ? -99 : Convert.ToInt32(Row["MyCol"]);

它与上面的If/Else获胜者的方法相同 - 但我发现如果你从一个数据加载器中读取多个列,这是一个真正的奖励,所有列读取行都在另一个下面,排成一行,因为它是更容易发现错误:

Object.ID = DataReader["ID"] == DBNull.Value ? -99 : Convert.ToInt32(DataReader["ID"]);
Object.Name = DataReader["Name"] == DBNull.Value ? "None" : Convert.ToString(DataReader["Name"]);
Object.Price = DataReader["Price"] == DBNull.Value ? 0.0 : Convert.ToFloat(DataReader["Price"]);



5> 小智..:

如果您可以控制返回结果的查询,则可以使用ISNULL()返回非空值,如下所示:

SELECT 
  ISNULL(name,'') AS name
  ,ISNULL(age, 0) AS age
FROM 
  names

如果您的情况可以容忍这些魔术值替换为NULL,那么采用这种方法可以解决整个应用程序中的问题,而不会使代码混乱.

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有