Получение значения NULL из базы данных и присвоение переменной Date

Хранимая процедура возвращает данные о записи пользователя, включая столбец даты и времени, допускающий значение NULL, для даты последнего входа в систему. Какой из них является лучшим выбором при работе с возможностью значений NULL при попытке назначить переменную даты .Net?

    Try
        _LastLogin = CDate(DT.Rows(0)("LastLogin"))
    Catch ex As InvalidCastException
        _LastLogin = Nothing
    End Try

or

    If DT.Rows(0)("LastLogin") Is DBNull.Value Then
        _LastLogin = Nothing
    Else
        _LastLogin = CDate(DT.Rows(0)("LastLogin"))
    End If

Изменить: я также забыл о возможности использования TryParse

    If Not Date.TryParse(DT.Rows(0)("LastLogin").ToString, _LastLogin) Then
        _LastLogin = Nothing
    End If

Какой метод обработки возможных значений NULL из базы данных является предпочтительным? Есть ли лучший способ, чем три перечисленных?

Правка №2. Я заметил, что метод TryParse плохо работает при попытке присвоить тип Nullable.


person TheTXI    schedule 11.03.2009    source источник
comment
Проблема с вашим методом TryParse заключается в том, что вы получите исключение, созданное методом ToString, если LastLogin имеет значение null.   -  person Kev    schedule 11.03.2009
comment
Кев: Если я не ошибаюсь, вызов ToString при извлечении NULL приведет к пустой строке (по крайней мере, так это работает для моей другой информации, извлеченной и сохраненной в строках). Однако, возможно, мне придется сделать еще одну проверку.   -  person TheTXI    schedule 11.03.2009
comment
Да, DBNull.Value.ToString() возвращает String.Empty   -  person bdukes    schedule 11.03.2009
comment
Кев: Я только что проверил это, сделав информацию другого столбца (которая вытягивается как строка) NULL, и она прошла через отладчик, используя .ToString, и присвоила значение строковой переменной.   -  person TheTXI    schedule 11.03.2009
comment
Если базовый столбец является строковым типом (например, varchar и т. д.), то вы совершенно правы, но я почти уверен, что нестроковые типы ToString() вызовут исключение, т.е. дату и время SQL.   -  person Kev    schedule 11.03.2009
comment
@TheTXI - да, ты прав, я исправляюсь. :)   -  person Kev    schedule 11.03.2009
comment
@Kev: по большому счету, TryParse не будет хорошо работать, если базовая переменная, которой я назначаю, имеет тип, допускающий значение NULL.   -  person TheTXI    schedule 11.03.2009
comment
@Kev: Так что ты не ошибся во всех смыслах.   -  person TheTXI    schedule 11.03.2009
comment
@TheTXI - наполовину неправильно, наполовину правильно - неплохой конец среды.   -  person Kev    schedule 11.03.2009


Ответы (5)


Второй фрагмент кода лучше. Исключения предназначены для исключительных случаев, а не для случаев, которые вы ожидаете. Кроме того, намерение намного лучше. Понятно, что вы ожидаете, что DBNull будет возможным значением, и вы хотите обработать его соответствующим образом.

Кроме того, у вас могут быть непредвиденные последствия, если значение не равно null, но не анализируется (хотя, скорее всего, этого никогда не произойдет).

person Matthew Bonig    schedule 11.03.2009

Второй метод предпочтительнее из-за затрат, связанных с созданием исключений (особенно если вы ожидаете, что поле LastLogin будет NULL на регулярной основе).

Вот хорошая запись в блоге с более подробной информацией о исключения (см. часть об исключениях и производительности).

person Ben Hoffstein    schedule 11.03.2009

Я использую класс FixDBNull:

Public Class FixDBNull(Of ItemType)    
    Public Shared Function Convert(ByVal data As Object) As ItemType
        If data IsNot System.DBNull.Value Then
            Dim obj As ItemType = Nothing

            Try
               obj = CType(data, ItemType)    
            Catch ex As Exception
                'do something with the conversion error
            End Try

            Return obj
        Else
            Return Nothing
        End If

End Function
End Class

то я могу назвать это так:

_LastLogin = FixDBNull(Of date).Convert( DT.Rows(0)("LastLogin"))

который вернет либо ничего, либо дату.

person user33209    schedule 11.03.2009

в VB.net он должен иметь значение Nullable (дата)

вот один из способов:

dim theDate as nullable(of Date)

    If theDate.HasValue Then
      'you can proceed
    Else
      'you must assign with DBNull.value
    End If

База данных также, вероятно, повлияет на то, что вы можете сделать. MS Access будет визжать о датах, несмотря ни на что. В конце концов я заставил это работать, но обычно я предпочитаю сохранять даты в виде строк в Access. Просто меньше хлопот в дороге.

person m42    schedule 11.03.2009

Я бы использовал TryCast, что будет выглядеть примерно так:

_LastLogin = TryCast(DT.Rows(0)("LastLogin"), Date?)
person bdukes    schedule 11.03.2009