String.IsNullOrEmpty 使用 IIF 和 IF ELSE 时验证中的 VS IsDBNull

String.IsNullOrEmpty VS IsDBNull in validation when using IIF and IF ELSE

我不清楚,所以如果有人能详细解释一下这两个函数有什么区别(IsDBNullString.IsNullOrEmpty) VB.Net.

下面是我问这个问题的原因,我的 table 中有列 Company,其值为 NULL,然后我使用了 IIF 函数 vb.net 验证它是否为 NULL 然后分配空字符串 (""),否则分配来自数据 table

的值

场景:

  1. 下面是使用 String.IsNullOrEmpty 我得到一个转换错误:

    Conversion from type 'DBNULL' to 'String' is not valid.

    txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))
    
  2. 但是当我用 IsDBNull 替换 String.IsNullOrEmpty 时,验证工作正常。

    txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))
    

编辑:

这很令人困惑,因为如果我使用 IF ELSE 条件(参见下面的示例代码)和 String.IsNullOrEmpty 进行验证,它工作正常。

    If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then
        txtCompany.Text = ""
    Else
        txtCompany.Text = dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString
    End If

令人困惑的部分是当我使用 IIF(String.IsNullOrEmpty...etc) 它 returns 时出错。但是当我使用正常的 IF String.IsNullOrEmpty(dtSample.Rows....etc) = True 时它工作正常。

任何解释将不胜感激。谢谢

IsNullOrEmpty function checks whether or not a string is empty or null. DBNull is not null (Nothing), but rather is a class that indicates a value from a database does not exist. IsDbNull 检查一个值是否等于 DBNull。

您可能没有得到您在引用的代码行问题中提到的错误,因为这对我来说运行得很好:

        strTest = IIf(String.IsNullOrEmpty(DBNull.Value.ToString), "", DBNull.Value)

IsDBNull 函数:

Returns 一个布尔值,指示表达式的计算结果是否为 System.DBNull class.

IsDBNull returns 如果 Expression 的数据类型评估为 DBNull 类型,则为真;否则,IsDBNull returns False。 System.DBNull 值表示对象表示缺失或不存在的数据。 DBNull 与 Nothing 不同,Nothing 表示一个变量还没有被初始化。 DBNull 也不同于零长度字符串 (""),后者有时被称为空字符串。

示例:

 Dim testVar As Object 
   Dim nullCheck As Boolean
      nullCheck = IsDBNull(testVar)
     testVar = ""
     nullCheck = IsDBNull(testVar)
     testVar = System.DBNull.Value
    nullCheck = IsDBNull(testVar)
     '  The first two calls to IsDBNull return False; the third returns True..

String.IsNullOrEmpty :

指示指定的字符串是空字符串还是空字符串。 IsNullOrEmpty 是一种方便的方法,可让您同时测试字符串是否为空或其值是否为空。

示例:

    Class Sample
   Public Shared Sub Main()
  Dim s1 As String = "abcd"
  Dim s2 As String = ""
  Dim s3 As String = Nothing

  Console.WriteLine("String s1 {0}.", Test(s1))
  Console.WriteLine("String s2 {0}.", Test(s2))
  Console.WriteLine("String s3 {0}.", Test(s3))
   End Sub

   Public Shared Function Test(s As String) As String
     If String.IsNullOrEmpty(s) Then
     Return "is null or empty"
    Else
     Return String.Format("(""{0}"") is neither null nor empty", s)
    End If
   End Function 
 End Class  
     'The example displays the following output:
    'String s1 ("abcd") is neither null nor empty.
     'String s2 is null or empty.
      'String s3 is null or empty.

TL;DR

  • String.IsNullOrEmpty() 仅检查 Empty([blank]''"")或 Nullnot 检查 DBNull,如果来自数据库的任何字段具有其值 DBNull,它将引发错误。
  • IsDBNull() 检查 DBNull(它与 Null 不同)
  • .ToString 会将 DBNull 转换为空字符串,即 ''

详情
考虑以下 SQL table 示例(使用 SQL 服务器作为基础)

Table结构:

Column_Name        Type and Size   Other Properties
----------------   -------------   ----------------------
Company_ID         int             IDENTITY(1,1) NOT NULL
Company_Name       nvarchar (50)                 NOT NULL   
Company_Address    nvarchar (50)                     NULL

插入语句:

INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('ABC', 'QWERT')
INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('ASD', ' ')
INSERT [tbl_company] ([Company_Name], [Company_Address]) VALUES ('XYZ', '')
INSERT [tbl_company] ([Company_Name])                    VALUES ('PQR')

Table数据:

Company_ID    Company_Name      Company_Address
-----------   ----------------  ---------------
1             ABC               QWERT
2             ASD               [SPACE]
3             XYZ               [BLANK]
4             PQR               NULL

使用 SqlDataReader (r) 使用 IsNullOrEmpty() 和 IsDBNull() 测试 Company_Address:

Company_ID IsNullOrEmpty(r("Company_Address")) IsDBNull(r("Company_Address"))
---------- ----------------------------------- ------------------------------
1          False                               False
2          False                               False
3          True                                False
4          ERROR                               True

现在具体到问题
OP 在这里尝试的是什么,让我们一个一个地考虑所有陈述

带有 IsNullOrEmpty 的 IIF 语句(错误

txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

在此语句中,OP 以 dtSample.Rows(grdInfo.SelectedIndex).Item("Company") 的形式访问值并使用 IsNullOrEmpty() 检查它,然后使用 .ToString 将 IsNullOrEmpty 的结果转换为字符串,即 IsNullOrEmpty(value).ToString()。如果该值为 DBNull,它总是 return 一个错误。正确的使用方法是

IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString)

参见最后一部分 Company")).ToStringCompany").ToString),只是 MISPLACED ")"

的一个例子

OP 的第二个(IIF with IsDBNull)和第三个(IF with IsNullOrEmpty)语句是正确的

txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then
    txtCompany.Text = ""
Else
    txtCompany.Text = dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString
End If

关于第二条语句,OP 正确排序了参数,即第一个 Company 字段使用 dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString 转换为字符串。这会将任何 DBNull 转换为空字符串,然后检查 IsNullOrEmpty。现在,由于该值已经转换为 EmptyString,因此不会出现任何错误。

与 OP 的旧讨论

您的文字中的区别很明显。您的第一个声明是:

txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSpecifierRebate.Rows(grdInfo.SelectedIndex).Item("Company"))

第二个是

If String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString) = True Then

现在把它们分开,第一个声明(IIF)

String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString
'Item("Company")).ToString

第二部分(IF)

String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company").ToString)
'Item("Company").ToString)

有什么不同吗?
在第一个语句中,您 将 IsNullOrEmpty 的结果转换为 String
在第二个中,您正在 转换 .Item("Company") ToString 然后比较它。

如果.Item("Company") returns DBNull
然后 IsNullOrEmpty 失败,因为 .Item("Company") returned type DBNull 而 IsNullOrEmpty 检查 null
IsDBNull 工作是因为它检查 DBNull

括号")"的所有点""错别字

关于您对这些语句的使用:
If 和 IIF 需要将结果检查为布尔值而不是字符串
最好删除语句的 ToString 部分

您不能混合搭配 String.IsNullOrEmptyIsDBNull,因为它们处理两种不同的事情。第一个关于字符串,第二个关于从数据库读取的数据项。

但是其中一个非常重要的因素是您的代码无效。 "Scenario" 片段都无法在 Option Strict 下编译。如果让 VB 去猜测你的意思,你会得到令人困惑的结果。

片段 1:

txtCompany.Text = IIf(String.IsNullOrEmpty(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

简化版:

Dim foo = IIf(String.IsNullOrEmpty(zDT.Rows(23).Item("Name")).ToString,
                "", zDT.Rows(23).Item("Name"))

这是非法的,因为 zDT.Rows(23).Item("Name") 是一个对象,但 String.IsNullOrEmpty 需要一个字符串。你的 ToString 放错地方了——它不是在转换数据库项目,而是在转换整个 IIF 布尔表达式!

编译器会用 Option Strict On 向您发出警告。

转换抛出异常,因为 VB 必须将数据库 Object 项 ( zDT.Rows(23).Item("Name")) 转换为字符串。当数据库数据为 DBNull 时,它的执行方式会导致错误。

片段 2:

txtCompany.Text = IIf(IsDBNull(dtSample.Rows(grdInfo.SelectedIndex).Item("Company")).ToString, "", dtSample.Rows(grdInfo.SelectedIndex).Item("Company"))

简化版:

foo = IIf(IsDBNull(zDT.Rows(23).Item("Name")).ToString, 
               "", zDT.Rows(23).Item("Name"))

这稍微好一点,但直到使用字符串代替布尔表达式。修复后,您有:

IsDBNull(zDT.Rows(23).Item("Name"))

IsDBNull 正在测试数据库项目(对象)以查看它是否有数据。它会起作用。 IsNullOrEmpty 不应用于测试 DBNull 并且不能与 Option Strict 一起使用。您必须先将 dbItem 转换为字符串,然后它才会起作用,具体取决于您的转换方式。

' cant use string method to test an object
String.IsNullOrEmpty(zDT.Rows(23).Item("Name"))

' this will work:
String.IsNullOrEmpty(zDT.Rows(23).Item("Name").ToString)

' this will not:
String.IsNullOrEmpty(CStr(zDT.Rows(23).Item("Name")))

对数据对象使用 DBNull 测试,对字符串使用 IsNullOrEmpty

此外,如果您使用更新的 If 运算符代替旧的 IIf 函数,则可以避免其他问题。运算符允许短路,语法相同:

Dim foo = If(bool expr, True result, False result)