VB.NET+Dapper:绑定源过滤后TextBox更新数据库及日期过滤问题
VB.NET Dapper 日期过滤问题解决指南
问题原因
日期过滤失效的核心原因是:直接调用c.DATE.ToString()进行字符串包含匹配时,DateTime类型默认的字符串格式(如"5/1/2024 12:00:00 AM")和你输入的"01-May-24"格式完全不一致,导致完整日期输入时无法匹配到任何结果。输入"01"时能命中,只是因为默认格式里包含了日的数字"1"(如"5/1/2024"中的"1")。
解决方案
1. 统一日期格式化进行过滤
将DateTime转换为和用户输入一致的固定格式字符串,再执行包含匹配:
Private Sub myFilter(str1 As String, str2 As String) Dim dateFormat As String = "dd-MMM-yy" ' 和数据库中显示的日期格式保持一致 If (String.IsNullOrEmpty(str1) AndAlso String.IsNullOrEmpty(str2)) Then bindingSource.DataSource = _criteriasBindingList ElseIf (String.IsNullOrEmpty(str1)) Then bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.DATE.ToString(dateFormat).ToLower().Contains(str2) ).ToList() ElseIf (String.IsNullOrEmpty(str2)) Then bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.NAMEPERSON.ToLower().Contains(str1) ).ToList() Else bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.NAMEPERSON.ToLower().Contains(str1) AndAlso c.DATE.ToString(dateFormat).ToLower().Contains(str2) ).ToList() End If End Sub
2. 替换KeyDown事件为TextChanged
KeyDown事件在粘贴文本等场景下不会触发,改用TextChanged能更及时响应输入变化:
Private Sub TXTNAME_TextChanged(sender As Object, e As EventArgs) Handles TXTNAME.TextChanged Dim str1 = TXTNAME.Text.Trim().ToLower() Dim str2 = TXTDATE.Text.Trim().ToLower() myFilter(str1, str2) End Sub Private Sub TXTDATE_TextChanged(sender As Object, e As EventArgs) Handles TXTDATE.TextChanged Dim str1 = TXTNAME.Text.Trim().ToLower() Dim str2 = TXTDATE.Text.Trim().ToLower() myFilter(str1, str2) End Sub
3. 修复UpdatePerson方法的SQL注入风险
原方法使用字符串拼接SQL存在严重安全漏洞,改用Dapper参数化查询:
Public Sub UpdatePerson(ByVal Obj As Person) Dim sql = "UPDATE PERSON INNER JOIN MASTERID ON (PERSON.ID = MASTERID.ID) " & _ "Set PERSON.TIME = @Time, PERSON.OTHERS1 = @Others1, PERSON.Others2 = @Others2 " & _ "WHERE MASTERID.NAMEPERSON = @NamePerson AND PERSON.DATE = @Date;" Using _conn = New OleDbConnection(GetOledbConnectionString()) _conn.Execute(sql, New With { .Time = Obj.TIME, .Others1 = Obj.OTHERS1, .Others2 = Obj.OTHERS2, .NamePerson = Obj.NAMEPERSON, .Date = Obj.DATE }) End Using End Sub
4. 可选:日期解析验证(进阶)
若要支持更灵活的日期输入,可尝试将用户输入解析为DateTime后比较日期部分:
Private Sub myFilter(str1 As String, str2 As String) Dim targetDate As DateTime? = Nothing If Not String.IsNullOrEmpty(str2) Then DateTime.TryParse(str2, targetDate) End If If (String.IsNullOrEmpty(str1) AndAlso targetDate Is Nothing) Then bindingSource.DataSource = _criteriasBindingList ElseIf (String.IsNullOrEmpty(str1)) Then bindingSource.DataSource = _criteriasBindingList.Where(Function(c) targetDate.HasValue AndAlso c.DATE.Date = targetDate.Value.Date ).ToList() ElseIf (targetDate Is Nothing) Then bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.NAMEPERSON.ToLower().Contains(str1) ).ToList() Else bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.NAMEPERSON.ToLower().Contains(str1) AndAlso c.DATE.Date = targetDate.Value.Date ).ToList() End If End Sub
其他注意事项
- 确保
dateFormat变量的值和用户输入的日期格式完全匹配(如"dd-MMM-yy"对应"01-May-24")。 - 若用户输入格式不固定,可使用
DateTime.TryParseExact指定多个可能的格式进行解析。 DataGridView.Refresh()仅刷新界面,如需重新加载数据,建议重新调用PersonService.GetPERSON()并更新BindingSource。
内容的提问来源于stack exchange,提问作者Tam88
相关产品推荐
相关产品推荐

