• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 865
  • Last Modified:

Strongly-Typed DataSet with Is<ColumName>Null and Iif function

Here's the story... I'm using VB.Net 2005 with a strongly-typed dataset.  Both Option Explicit and Option Strict are enabled.  The underlying database is SQL 2005 Express (but that's probably not relevant).

In one of my Tables, a string column allows for nulls, so it automatically generated a Is<ColumnName>Null function for me.   So far, so good...

However, when I use the Is<ColumnName>Null inside an IIF() Statement, both the true and false parts get evaluated (even if the expression evaluates to True)

Take a look at the following to see what I'm talking about...

    Overrides Function ToString() As String
        Dim sb As New System.Text.StringBuilder
        Dim dr As SOSOSDataSet.AccountsRow

        For Each dr In _ds.Accounts                             '<- ds = Strongly-Typed DataSet with Account table
            sb.Append("Account=" & dr.Account & vbCr)

            ' Neither of the 2 following lines work!  The dr.Account_FullName method gets evaluated regardless
            ' of the outcome of the expression.  And, when it evaluated to null, it generates an exception
            'sb.Append(vbTab & "FullName=" & CStr(IIf(dr.IsAccount_FullNameNull, "", dr.Account_FullName)) & vbCr)
            'sb.Append(vbTab & "FullName=" & IIf(dr.IsAccount_FullNameNull, "", dr.Account_FullName).ToString & vbCr)

            ' Oddly enough, using an normal If/Else/End if statement works!
            If dr.IsAccount_FullNameNull Then                '<- Automatically generated IsNull function
                sb.Append(vbTab & "FullName=" & vbCr)
                sb.Append(vbTab & "FullName=" & dr.Account_FullName & vbCr)
            End If

            ' Using the old-school IsDBNull function and the "native" DataRow interface
            ' Doesn't work any better inside an IIF statement
            'sb.Append(vbTab & "FullName=" & CStr(IIf(IsDBNull(dr("Account_FullName")), "", dr.Account_FullName)) & vbCr)

            ' However, this works just fine!
            If IsDBNull(dr("Account_FullName")) Then
                sb.Append(vbTab & "FullName=" & vbCr)
                sb.Append(vbTab & "FullName=" & dr.Account_FullName & vbCr)
            End If

            'sb.Append(vbTab & "Description=" & CStr(IIf(dr.IsAccount_FullNameNull, "", dr.Account_FullName))) & vbCr)
            sb.Append(vbTab & "Disabled=" & dr.Account_Disabled.ToString & vbCr)
            sb.Append(vbTab & "LockedOut=" & dr.Account_LockedOut.ToString & vbCr)
            sb.Append(vbTab & "PwdRequired=" & dr.Account_PwdRequired.ToString & vbCr)
            sb.Append(vbTab & "LockedOut=" & dr.Account_PwdChangeable.ToString & vbCr)
            sb.Append(vbTab & "PwdRequired=" & dr.Account_PwdExpires.ToString & vbCr)

        Return sb.ToString
    End Function

I think I'm going crazy... either that or I've found a bug.

Isn't the IIF function supposed to "Short Cut" the evaluation of the arguments?
1 Solution
grayeAuthor Commented:
Hummm... The MSIL shows that it's evaluating both the true and false parameters, poping them on the stack, and then executing the IIF

      L_0047: ldstr "\tFullName="
      L_004c: ldloc.0
      L_004d: callvirt instance bool SOSOS.SOSOSDataSet/AccountsRow::IsAccount_FullNameNull()
      L_0052: ldstr ""
      L_0057: ldloc.0
      L_0058: callvirt instance string SOSOS.SOSOSDataSet/AccountsRow::get_Account_FullName()
      L_005d: call object [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::IIf(bool, object, object)

So, I guess it's just me...

Is there an "in-line" equivalent of IIF that mirrors the behavior of the "? :" operators in C#
When doing the iif, first it evaluates all arguments, then if performs the condition. So, when the expression is null, it will first try to evaluate it regardless of the condition - and that's why it throws an exception. The exception is not being thrown by iif but by your dataset, since iif is trying to retrieve the null value - keep that in mind.

I would do something like this
Dim FullName As String = ""
If Not dr.IsAccount_FullNameNull Then FullName = dr.Account_FullName

in your string builder:

sb.append("FullName=" & FullName)



Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now