问题:
我正在开发一个 ASP.NET WebForms 应用程序,我需要根据日期范围过滤
DataTable
中的记录。使用 FromMonth
、ToMonth
、FromYear
和 ToYear
下拉菜单选择日期范围。目标是在 RadGrid
中显示过滤后的数据,但我的过滤逻辑未按预期工作。有时,没有数据显示,或者结果不正确。
问题:
基于
PADate
字段的过滤逻辑未按预期工作。即使我使用下拉菜单选择有效的日期范围,网格也不会显示任何数据或显示错误的结果。
我采取的调试步骤:
已验证数据库中的
PADate
字段的 DateTime
格式是否正确。
检查下拉列表中的值(
FromMonth
、ToMonth
、FromYear
和ToYear
)是否正确。
确保
PADate
字段在过滤逻辑中正确解析为 DateTime
值。
预期结果:
我希望网格仅显示
PADate
位于所选日期范围内(从 FromMonth/FromYear
到 ToMonth/ToYear
)的记录。
代码:
这是我用来过滤数据的方法:
protected void PCApplicationStatus()
{
try
{
// Get the selected values from dropdowns
int fromMonth = int.Parse(FromMonth.SelectedValue);
int toMonth = int.Parse(ToMonth.SelectedValue);
int fromYear = int.Parse(FromYear.SelectedValue);
int toYear = int.Parse(ToYear.SelectedValue);
// Create date range
DateTime startDate = new DateTime(fromYear, fromMonth, 1);
DateTime endDate = new DateTime(toYear, toMonth, DateTime.DaysInMonth(toYear, toMonth));
// Validate that 'From' date is earlier than 'To' date
if (fromYear > toYear || (fromYear == toYear && fromMonth > toMonth))
{
throw new InvalidOperationException("The 'From' date must be earlier than the 'To' date.");
}
// Fetch data from database
AdDAL obj = new AdDAL();
DataSet ds = obj.ExecutePaymentClaimQuery();
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
DataTable dt = ds.Tables[0];
DataTable filteredDt = dt.Clone(); // Clone the structure of the original table
// Filter rows based on the date range
foreach (DataRow dr in dt.Rows)
{
DateTime? paDate = dr["PADate"] is DBNull ? (DateTime?)null : Convert.ToDateTime(dr["PADate"]);
if (paDate.HasValue && paDate.Value >= startDate && paDate.Value <= endDate)
{
filteredDt.ImportRow(dr); // Import rows that fall within the date range
}
}
// Bind the filtered data to the grid
if (filteredDt.Rows.Count > 0)
{
Grid.DataSource = filteredDt;
}
else
{
Grid.DataSource = null; // No matching rows found
}
Grid.DataBind(); // Rebind the grid with the filtered data
}
else
{
// No data available
Grid.DataSource = null;
Grid.DataBind();
}
}
catch (Exception ex)
{
// Log the error
Console.WriteLine("Error: " + ex.ToString());
}
}
您有一个数据库引擎,因此尝试编写循环代码来过滤数据根本就是错误的方法,而且工作量太大。
而且,看起来您正在使用数据集设计器,这允许您将自定义方法添加到使用数据集设计器创建的数据集中。
因此,为您现有的数据适配器构建(添加)一个新的适配器方法。
举个例子:
然后是这个:
所以,现在表适配器有了参数。
因此,您的代码现在将变成这样:
// Create date range
DateTime startDate = new DateTime(fromYear, fromMonth, 1);
DateTime endDate = new DateTime(toYear, toMonth, DateTime.DaysInMonth(toYear, toMonth));
if (startDate > endDate)
{
// display message to user and exit
string sJava = @"alert('starting date cannot be\ngreater then end date')";
ScriptManager.RegisterStartupScript(this, this.GetType(), "myjava", sJava, true);
return;
}
GridView1.DataSource = da.GetDataByDate(startDate, endDate);
GridView1.DataBind();
并且,如果由于某种原因您无法添加或更改现有的数据集和方法?
再一次,不需要循环代码。假设您喜欢额外的工作,并且不按照上面的方式更改数据集?然后您可以根据表格进行过滤。
我们的代码将变成这样:
// Create date range
DateTime startDate = new DateTime(fromYear, fromMonth, 1);
DateTime endDate = new DateTime(toYear, toMonth, DateTime.DaysInMonth(toYear, toMonth));
if (startDate > endDate)
{
// display message to user and exit
string sJava = @"alert('starting date cannot be\ngreater then end date')";
ScriptManager.RegisterStartupScript(this, this.GetType(), "myjava", sJava, true);
return;
}
DataTable dtHotels = da.GetData();
string strFiler =
$"[BookingDate] >= '{startDate.ToShortDateString()}' " +
$"AND [BookingDate] <= '{endDate.ToShortDateString()}'";
dtHotels.DefaultView.RowFilter = strFiler;
GridView1.DataSource = dtHotels.DefaultView;
GridView1.DataBind();
因此,当您拥有专为此类任务设计的整个数据库系统时,编写循环代码没有什么意义。
错误的输入日期范围不应触发代码错误,并且您不会向最终用户提供任何反馈。
所以,对上面的代码说出这个标记:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="ID"
CssClass="table table-hover" Width="50%"
>
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Descripiton" />
<asp:BoundField DataField="BookingDate" DataFormatString="{0:d}"
HeaderText="Booking Date"
ItemStyle-Width="120"
/>
</Columns>
</asp:GridView>
因此,对于输入开始日期>结束日期,我们有这样的效果:
并且,假设一个有效的日期,那么我们会得到这样的效果: