DateTime обнуляемое исключение в качестве параметра - PullRequest
0 голосов
/ 08 мая 2009

У меня есть поисковая форма, которая может искать по нескольким различным полям. Проблемное поле - дата рождения. На форме это строка. В базе данных SQL 2005 это DateTime, который может быть нулевым.

Приведенный ниже код является последовательным, поскольку объявляет переменную в форме и затем устанавливает ее. Затем вызов в BLL и затем вызов в DAL.

В этой строке ->

dgvSearchResults.DataSource =ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN, (DateTime)_birthDate,_applicationID,_applicationPersonID,_fuzzy);

Я получаю «Обнуляемый объект должен иметь значение» Ошибка.

Я предполагаю, потому что я не дал параметр Date, а затем попытался привести к необнуляемому DateTime. Правильно?

Что я могу с этим сделать? Должен быть способ обойти это. Точно такая же BLL & DAL работает над версией веб-приложения.

РЕДАКТИРОВАТЬ 1

Несколько замечаний. У меня сложилось впечатление, что DateTime? был таким же, как Nullable<DateTime> Правильно?

Кроме того, я не вижу, как я могу вставить произвольное значение для поля, такого как BirthDate. Я полагаю, я мог бы встроить несколько фильтров в свой бизнес-уровень, но это похоже на «хак». Возможно, нет. Кроме того, меня беспокоит, что эти же BLL и DAL с этой же БД допускают пустые значения в поле BirthDate в версии этой программы для WebApp. Есть идеи? В БД есть ноль для тех записей без даты.

Search.cs

public DateTime? _birthDate;
_birthDate = null;
if (datBirthDate.Text != string.Empty)
    _birthDate = Convert.ToDateTime(datBirthDate.Text);
dgvSearchResults.DataSource=ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN, (DateTime)_birthDate,_applicationID,_applicationPersonID,_fuzzy);

ConnectBLL -> Person.vb

Public Shared Function Search(ByVal firstName As String, ByVal middleName As String, ByVal lastName As String, ByVal SSN As String, ByVal birthDate As Date, ByVal applicationId As Integer, ByVal applicationPersonId As String, ByVal fuzzy As Boolean) As Data.DataTable
Try
    Dim tbl As Data.DataTable = DAL.Connect.SearchPerson(firstName, middleName, lastName, SSN, birthDate, applicationId, applicationPersonId, fuzzy)

    If tbl.Rows.Count > 0 Then
        tbl.DefaultView.Sort = "Last Name ASC, First Name ASC, Middle Name ASC"
    End If
    Return tbl
Catch
    Throw
End Try

Функция завершения

ConnectDAL -> Connect.vb

Public Shared Function SearchPerson(ByVal _FirstName As String, ByVal _MiddleName As String, ByVal _LastName As String, ByVal _SSN As String, ByVal _BirthDate As Date, ByVal _ApplicationID As Integer, ByVal _ApplicationPersonID As String, ByVal _Fuzzy As Boolean) As Data.DataTable
Dim test As New clsSqlResponseTime
Dim dt As New Data.DataTable
Try
    Using cnn As New SqlClient.SqlConnection(ConnectROConnectionString)
        Dim cmd As New SqlClient.SqlCommand()
        cmd.Connection = cnn
        If _Fuzzy Then
            cmd.CommandText = strSearchPersonFuzzyStoredProcedure
        Else
            cmd.CommandText = strSearchPersonStoredProcedure
        End If
        cmd.CommandType = CommandType.StoredProcedure
        If Not IsNothing(_FirstName) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@FirstName", _FirstName))
        If Not IsNothing(_MiddleName) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@MiddleName", _MiddleName))
        If Not IsNothing(_LastName) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@LastName", _LastName))
        If Not IsNothing(_SSN) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@SSN", _SSN))
        If Not (_BirthDate = Date.MinValue) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@BirthDate", _BirthDate))
        If Not IsNothing(_ApplicationPersonID) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@ApplicationID", _ApplicationID))
        If Not IsNothing(_ApplicationPersonID) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@ApplicationPersonID", _ApplicationPersonID))

        Dim da As New SqlClient.SqlDataAdapter(cmd)
        da.Fill(dt)
    End Using
Catch
    Throw
End Try
test.Log("SearchPerson", "Connect")
Return dt

Функция завершения

Ответы [ 4 ]

1 голос
/ 09 мая 2009

Мне кажется, что вы вообще не используете значение birthDate до третьей функции, где оно добавляется в коллекцию Parameters. В этой третьей функции она уже проверяется с помощью Date.MinValue перед добавлением. Просто измените первую функцию на это:

public DateTime _birthDate;
if (string.IsNullOrEmpty(datBirthDate.Text))
    _birthDate = DateTime.MinValue;
else
    _birthDate = Convert.ToDateTime(datBirthDate.Text);
dgvSearchResults.DataSource=ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN,_birthDate,_applicationID,_applicationPersonID,_fuzzy);

Это самый простой выход, но не обязательно самый правильный. Я бы изменил все три функции, чтобы использовать Nullable DateTime следующим образом:

Функция 1

public DateTime? _birthDate = null;
if (!string.IsNullOrEmpty(datBirthDate.Text))
    _birthDate = Convert.ToDateTime(datBirthDate.Text);
dgvSearchResults.DataSource=ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN,_birthDate,_applicationID,_applicationPersonID,_fuzzy);

Определения функций 2 и 3 должны выглядеть следующим образом:

Public Shared Function Search(ByVal firstName As String, ByVal middleName As String, ByVal lastName As String, ByVal SSN As String, ByVal birthDate As Nullable(Of Date), ByVal applicationId As Integer, ByVal applicationPersonId As String, ByVal fuzzy As Boolean) As Data.DataTable

Public Shared Function SearchPerson(ByVal _FirstName As String, ByVal _MiddleName As String, ByVal _LastName As String, ByVal _SSN As String, ByVal _BirthDate As Nullable(Of Date), ByVal _ApplicationID As Integer, ByVal _ApplicationPersonID As String, ByVal _Fuzzy As Boolean) As Data.DataTable

И строка в функции 3, которая использует birthDate:

If (_BirthDate.HasValue) Then cmd.Parameters.Add(New SqlClient.SqlParameter("@BirthDate", _BirthDate.Value))
1 голос
/ 08 мая 2009

Похоже, вы пытаетесь привести возможное значение Null к DateTime в Search.cs в этой строке.

dgvSearchResults.DataSource = ConnectBLL.BLL.Person.Search (_firstName, _middleName, _lastName, _sSN, (DateTime) _birthDate, _applicationID, _applicationPersonID, _fuzzy);

Это вызвало бы эту ошибку. Если строка пуста, вы приведете null к DateTime, который взорвется. Я предлагаю вашему методу Person.Search взять Nullable в качестве параметра и обработать там нулевой регистр или установить его в DateTime.MinValue и обработать его как ноль в Person.Search.

1 голос
/ 08 мая 2009

Вы можете сделать что-то вроде этого:

dgvSearchResults.DataSource=ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN, _birthDate.HasValue ? _birthDate.Value : new DateTime() ,_applicationID,_applicationPersonID,_fuzzy);

По сути, если оно равно null, просто установите его по умолчанию, равное значению по умолчанию для DateTime (я полагаю, это 1/1/0001).

0 голосов
/ 09 мая 2009

Вместо установки _birthDate на ноль, почему бы не установить его с некоторым значением DateTime? Таким образом, передача вызова BLL не может быть нулевой. Либо DateTime.MinValue, либо DateTime.Now могут работать.

...