我有一个可以搜索几个不同字段的搜索表单。问题字段是birthDate。在表单上它是一个字符串。在SQL 2005 db中,它是一个DateTime,可以为null。
下面的代码是顺序的,只要在表单上声明变量然后进行设置即可。然后调用BLL然后调用DAL。
在这一行 - >
dgvSearchResults.DataSource =ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN, (DateTime)_birthDate,_applicationID,_applicationPersonID,_fuzzy);
我得到一个“Nullable对象必须有值”错误。
我假设因为我没有给出Date参数,然后尝试转换为不可为空的DateTime。正确的吗?
我该怎么办?必须有一种解决方法。这完全相同的BLL& DAL适用于Web应用程序版本。
有几点需要注意。我的印象是DateTime?
与Nullable<DateTime>
正确相同?
另外,我不知道如何为BirthDate之类的字段输入任意值。我想我可以在我的业务层中构建一堆过滤器,但这似乎是“Hack”的方式。也许不吧。此外,令我困扰的是,具有相同DB的相同BLL和DAL允许此程序的WebApp版本中的BirthDate字段中的空值。有什么想法吗?对于没有日期的条目,数据库中包含 null 。
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 - &gt; 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 - &gt; 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
结束功能
答案 0 :(得分:1)
您可以这样做:
dgvSearchResults.DataSource=ConnectBLL.BLL.Person.Search(_firstName,_middleName,_lastName,_sSN, _birthDate.HasValue ? _birthDate.Value : new DateTime() ,_applicationID,_applicationPersonID,_fuzzy);
基本上,如果它为null,只要默认为DateTime的默认值(我相信它是1/1/0001)。
答案 1 :(得分:1)
您似乎试图在此行的Search.cs中将可能的Null值转换为DateTime。
dgvSearchResults.DataSource = ConnectBLL.BLL.Person.Search(_ firstName,_middleName,_lastName,_sSN,(DateTime)_birthDate,_applicationID,_applicationPersonID,_fuzzy);
这会导致此错误。如果字符串为空,则会将null转换为DateTime,这将会爆炸。我建议你的Person.Search方法采用Nullable&lt; DateTime&gt;作为参数并在那里处理null case或将其设置为DateTime.MinValue并在Person.Search中将其视为null。
答案 2 :(得分:1)
在我看来,你根本没有使用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))
答案 3 :(得分:0)
为什么不设置一些DateTime值,而不是将_birthDate设置为null?这样就不能将null传递给BLL调用。 DateTime.MinValue或DateTime.Now都可以工作。