注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

飞天心宏的博客

依稀旧梦似曾见,相逢只恨缘太迟

 
 
 

日志

 
 
关于我

出身数学,爱好文学,从事软件开发工作。一个阳光、幽默、热爱生活的男孩子,在追求理想的路上风雨无阻,勇往直前,崇尚“梦想有多远,我们就走多远”!

网易考拉推荐

C#中的DBNull、Null和String.Empty解释  

2009-09-19 17:30:02|  分类: C#编程参考 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

备注:以下来自MSDN和网络参考,经过整理后的文档

1.DBNull的解释:
   
该类用于指示不存在某个已知值(通常在数据库应用程序中)

在数据库应用程序中,空对象是字段的有效值。该类区分空值(空对象)和未初始化值(DBNull.Value实例)。例如,表可以包含具有未初始化字段的记录。默认情况下,这些未初始化字段具有DBNull值。

DBNull 从不等于任何值。DBNull是一个单独的类,这意味着该类只能存在一个实例。这个唯一的实例是 DBNull.Value。访问 SQL 数据库的数据密集应用程序必须使用 System.Data.SqlTypes 类,这些类对空值具有内在支持。

DBNullDotNet是单独的一个类型,该类只能存在唯一的实例,DBNULL.Value,DBNull唯一作用是可以表示数据库中的字符串,数字,或日期,为什么可以表示原因是DotNet储存这些数据的类(DataRow等)都是以 object 的形式来储存数据的。对于 DataRow , 它的 row[column] 返回的值永远不为 null 要么就是具体的为column 的类型的值 。要么就是 DBNull 所以 row[column].ToString() 这个写法永远不会在ToString那里发生NullReferenceExceptionDBNull 实现了 IConvertible 。但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。

 

MSDNDBNULL类表示不存在的值。无法继承此类。

DBNull 类表示一个不存在的值。例如,在数据库的表中,某一行的某列中可能不包含任何数据。即,该列被视为根本不存在,而不只是没有值。一个表示不存在的列的 DBNull 对象。此外,COM 互操作使用 DBNull 类来区分 VT_NULL 变量(指示不存在的值)和 VT_EMPTY 变量(指示未指定的值)。

DBNull 类型是一个单独的类,这意味着只有一个 DBNull 对象存在。DBNull..::.Value 成员表示唯一的 DBNull 对象。DBNull..::.Value 可用于将不存在的值显式分配给数据库字段,但大多数 ADO.NET 数据提供程序在字段没有有效值时会自动分配 DBNull 值。您可以通过将从数据库字段检索到的值传递给 DBNull.Value.Equals 方法,确定该字段值是否为 DBNull 值。然而,有些语言和数据库对象提供一些方法,可以更容易地确定数据库字段值是否为 DBNull..::.Value。这些方法包括 Visual Basic IsDBNull 函数、Convert..::.IsDBNull 方法、DataTableReader..::.IsDBNull 方法和 IDataRecord..::.IsDBNull 方法。

请勿将面向对象的编程语言中的 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing 概念与 DBNull 对象混淆。在面向对象的编程语言中,nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing 表示不存在对某个对象的引用。DBNull 则表示未初始化的变量或不存在的数据库列。

 

2.Null 的解释

null 关键字是表示不引用任何对象的空引用的文字值。null 是引用类型变量的默认值。那么也只有引用型的变量可以为NULL,如果 int i=null,的话,是不可以的,因为Int是值类型的。
    "null" means the object reference  is invalid in .NET,  when you   retrieve a NULL value from the  Database,it is a valid value to .NET, and it is  represented   bySystem.DBNull.Value


  

  MSDNnull 关键字是表示不引用任何对象的 null 引用的文字值。null 是引用类型变量的默认值。C# 2.0 引入了可为 null 的类型,这是可以设置成未定义值的数据类型。

 

扩展:可以为 null 的类型(C# 编程指南)

可以为 null 的类型是 System..::.Nullable<(Of <(T>)>) 结构的实例。可以为 null 的类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。例如,Nullable<Int32> 读作可以为 null Int32,可以将其赋值为 -2147483648 2147483647 之间的任意值,也可以将其赋值为 null 值。可以赋给 Nullable<bool> 的值包括 truefalse null。在处理数据库和其他包含不可赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。例如,数据库中的布尔型字段可以存储值 true false,或者,该字段也可以未定义。

可以为 null 的类型具有以下特性:

·         可以为 null 的类型表示可被赋值为 null 值的值类型变量。无法创建基于引用类型的可以为 null 的类型。(引用类型已支持 null 值。)

·         语法 T? Nullable<(Of <(T>)>) 的简写,此处的 T 为值类型。这两种形式可以互换。

·         为可以为 null 的类型赋值的方法与为一般值类型赋值的方法相同,如 int? x = 10; double? d = 4.108;

·         如果基础类型的值为 null,请使用 Nullable<(Of <(T>)>)..::.GetValueOrDefault 属性返回该基础类型所赋的值或默认值,例如 int j = x.GetValueOrDefault();

·         请使用 HasValue Value 只读属性测试是否为空和检索值,例如 if(x.HasValue) j = x.Value;

·         如果此变量包含值,则 HasValue 属性返回 True;或者,如果此变量的值为空,则返回 False

·         如果已赋值,则 Value 属性返回该值。否则,将引发 System..::.InvalidOperationException

·         可空类型变量的默认值将 HasValue 设置为 false。未定义 Value

·         使用 ?? 运算符分配默认值,当前值为空的可以为 null 的类型被赋值给非空类型时将应用该默认值,如 int? x = null; int y = x ?? -1;

·         不允许使用嵌套的可以为 null 的类型。将不编译下面一行:Nullable<Nullable<int>> n;

 

class NullableExample

{

    static void Main()

    {

        int? num = null;

        if (num.HasValue == true)

        {

            System.Console.WriteLine("num = " + num.Value);

        }

        else

        {

            System.Console.WriteLine("num = Null");

        }

 

        //y is set to zero

        int y = num.GetValueOrDefault();

 

        // num.Value throws an InvalidOperationException if num.HasValue is false

        try

        {

            y = num.Value;

        }

        catch (System.InvalidOperationException e)

        {

            System.Console.WriteLine(e.Message);

        }

    }

}

 

此示例将显示输出:

num = Null

Nullable object must have a value.

 

3.""String.Empty

这两个都是表示空字符串,其中有一个重点是string str1="" string str2=null 的区别,这样定义后,str1是一个空字符串,空字符串是一个特殊的字符串,只不过这个字符串的值为空,在内存中是有准确的指向的,string str2=null,这样定义后,只是定义了一个string 类的引用,str2并没有指向任何地方,在使用前如果不实例化的话,都将报错。

 

下面示例中,Compare 中使用了 Empty 字符串来测试子字符串:

String myString = "abc";

bool test1 = String.Compare(myString.Substring(2, 1), "c") == 0;// This is true.

myString.Substring(3, 1); // This throws ArgumentOutOfRangeException.

bool test2 = String.Compare(myString.Substring(3, 0), String.Empty) == 0; // This is true.

 

    4.Convert.IsDBNull()

Convert.IsDBNull()返回有关指定对象是否为 DBNull 类型的指示,即是用来判断对象是否为DBNULL的。其返回值是TrueFlase
     DBNull
DotNet是单独的一个类型 System.DBNull 。它只有一个值 DBNull.Value DBNull 直接继承 Object ,所以 DBNull 不是 string , 不是 int , 也不是 DateTime …… 但是为什么 DBNull 可以表示数据库中的字符串,数字,或日期呢?原因是DotNet储存这些数据的类(DataRow等)都是以 object 的形式来储存数据的。对于 DataRow , 它的 row[column] 返回的值永远不为 null ,要么就是具体的为column 的类型的值。要么就是DBNull.所以 row[column].ToString() 这个写法永远不会在ToString那里发生NullReferenceException

DBNull 实现了 IConvertible 但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。

IDbCommand(OleDbCommand,SqlCommand...) ExecuteScalar的返回值中,情况可以这样分析:

select 1 这样返回的object 1

select null 这样返回的是DBNull.Value

select isnull(null,1) 返回的是 1

select top 0 id from table1 这样返回的值是null

select isnull(id,0) from table1 where 1=0 返回的值是null

这里 ExecuteScalar 的规则就是,返回第一列,第一行的数据。如果第一列第一行不为空,那么ExecuteScalar就直接对应的DotNet的值。如果有第一行,但是第一列为空,那么返回的是 DBNull 。如果一行都没有,那么ExecuteScalar就返回null .

规则就是这样的。这里容易犯的一个错误是,把ExecuteScalar返回DBNullnull的情况混淆,例如:

string username=cmd.ExecuteScalar().ToString()

除非你认为cmd执行后,肯定至少有一行数据,否则这里就会出错。又或者 select id from usertable where username=@name 这样的sql语句,如果找不到记录,那么ExecuteScalar则会返回null,所以千万不要

int userid=Convert.ToInt32(cmd.ExecuteScalar());

或者你会这样写 SQL 语句:

select isnull(id,0) from usertable where username=@name

 

但是 int userid=Convert.ToInt32(cmd.ExecuteScalar()); 依然会出错,因为上面的语句不成立时,仍然是不返回任何行。

对于IDbDataParameter(OleDDbParameter,SqlParameter..)Value,如果为null,则代表该参数没有指定,或者是代表DEFAULT。如果为DBNull.Value,则代表SQL中的NULL .所以,如果你要调用存储过程,里面有参数 @val nvarchar(20)="AABB" ,那么cmd.Parameters["@val"].Value=null 代表使用这个默认的 "AABBcmd.Parameters["@val"].Value=DBNull.Value 代表使用NULL来传给 @val 你可以用Convert.IsDBNull来判断一个值是否DBNull。注意Convert.IsDBNull(null)false

 

                                整理:飞天心宏 2009-9-19

                                 

 

  评论这张
 
阅读(1523)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017