繁体   English   中英

DateTime可为空的异常作为参数

[英]DateTime nullable exception as a parameter

我有一个搜索表单,可以按几个不同的字段进行搜索。 问题字段是birthDate。 在表格上是一个字符串。 在SQL 2005数据库中,它是一个DateTime,可以为null。

下面的代码是顺序的,直到在窗体上声明变量然后进行设置。 然后调用BLL,然后调用DAL。

在这行->

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

我收到“可为空的对象必须具有值”错误。

我以为是因为我没有提供Date参数,然后尝试强制转换为不可为null的DateTime。 正确?

我该怎么办? 必须有一种解决方法。 Web应用程序版本上与此完全相同的BLL和DAL工作。

编辑1

需要注意的几件事。 我对DateTime?有印象DateTime? Nullable<DateTime>正确吗?

另外,我看不到如何为BirthDate这样的字段输入任意值。 我想我可以在业务层中构建一堆过滤器,但这似乎是“骇客”的方式。 也许不吧。 同样,令我困扰的是,该程序的WebApp版本中的BirthDate字段中的相同BLL和DAL以及相同的DB允许为空。 有什么想法吗? 对于那些没有日期的条目,数据库中具有空值

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

结束功能

您可以执行以下操作:

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

基本上,如果为null,则将其默认设置为DateTime的默认设置(我相信它是1/1/0001)。

您似乎正在尝试在此行上将可能的Null值转换为Search.cs中的DateTime。

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

那会导致这个错误。 如果字符串为空,则将null转换为DateTime,否则它将被炸毁。 我建议您的Person.Search方法将Nullable <DateTime>作为参数并在那里处理null大小写,或将其设置为DateTime.MinValue并将其在Person.Search中视为null。

在我看来,直到第三个函数将其添加到Parameters集合中,您才根本不使用birthDate值。 在第三个函数中,已经在添加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))

为什么不将_birthDate设置为null,而不用某些DateTime值设置它? 这样,它不能为null传递给BLL调用。 DateTime.MinValue或DateTime.Now都可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM