具有日期范围的数据表过滤器

DataTable Filter with range of dates

我正在处理的程序的一部分需要过滤掉所有不必要的行,并且只根据从我表单上的日期时间选择器控件中选择的开始和结束日期保留必要的行. .csv 文件包含以下示例中的所有日期:

如果我的日期时间选择器选择开始日期为 2015 年 2 月 18 日,结束日期为 2015 年 3 月 2 日,我希望我的数据中只包含这些项目 table.我已经有一种方法可以反转数据行,但我需要知道如何准确地过滤掉小于或等于结束日期以及大于或等于开始日期的值。 我的计划是在一个单独的方法中完成过滤,在该方法中我传递通过读取 .csv 文件创建的现有 table。

到目前为止我的代码如下:

public DataTable PopulateTable()
{
    DataTable stockTable = new DataTable();
    try
    {
        FileStream stream = new FileStream(BuildFilePath(), FileMode.Open);
        stream.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Unable to open filepath");
    }

    StreamReader reader = new StreamReader(BuildFilePath());
    string header = "";
    string line = "";
    char[] delimeter = { ',' };
    string[] headerData;
    string[] rowData;
    //read the header and add the names to the columns of the data table
    header = reader.ReadLine();
    headerData = header.Split(delimeter);
    for (int i = 0; i < 5; ++i)
    {
        if (i == 0)
        {
            stockTable.Columns.Add(new DataColumn(headerData[i], typeof(DateTime)));
        }
        else
            stockTable.Columns.Add(new DataColumn(headerData[i], typeof(decimal)));
    }
    //read each line and populate the data table rows
    while (reader.Peek() > -1)
    {
        line = reader.ReadLine();
        rowData = line.Split(delimeter);
        stockTable.Rows.Add(rowData[0], rowData[1], rowData[2], rowData[3], rowData[4]);
    }
    reader.Close();

    //before the table is returned here call the FilterTable function

    return ReverseRowsInDataTable(stockTable);
}

private DataTable ReverseRowsInDataTable(DataTable table)
{
    DataTable reversedDataTable = table.Clone();
    for (int i = table.Rows.Count - 1; i >= 0; --i)
    {
        reversedDataTable.ImportRow(table.Rows[i]);
    }
    return reversedDataTable;
}

private DataTable FilterTable(DataTable table)
{
    DataTable filteredTable = new DataTable();
    return filteredTable;
}

我不明白你为什么要反转数据中的行table。从我的角度来看,这是没有必要的。

您可以使用 Linq 查询筛选行,如下所示:

private DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
{
    var filteredRows =
        from row in table.Rows.OfType<DataRow>()
        where (DateTime) row[0] >= startDate
        where (DateTime) row[0] <= endDate
        select row;

    var filteredTable = table.Clone();

    filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));

    return filteredTable;
} 

要return 具有相同结构的数据表,您可以使用.Clone() 方法并向这个新创建的table.

添加过滤的行

编辑

你可以同时做相反的事情。如果您在填充时在索引 1 处添加一个额外的 int 列,并在此处插入行号,如下所示:

for (int i = 0; i < 6; ++i)
{
    if (i == 0)
    {
        stockTable.Columns.Add(new DataColumn(headerData[i], typeof(DateTime)));
    }
    else if (i == 1)
    {
        stockTable.Columns.Add(new DataColumn("RowNbr", typeof(int)));
    }
    else
        stockTable.Columns.Add(new DataColumn(headerData[i-1], typeof(decimal)));
}
//read each line and populate the data table rows
int j = 0;
while (reader.Peek() > -1)
{
    line = reader.ReadLine();
    rowData = line.Split(delimeter);
    stockTable.Rows.Add(rowData[0], j++, rowData[1], rowData[2], rowData[3], rowData[4]);
}

反转数据可以很简单:

private DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
{
    var filteredRows =
        from row in table.Rows.OfType<DataRow>()
        where (DateTime)row[0] >= startDate
        where (DateTime)row[0] <= endDate
        orderby (int)row[1] descending 
        select row;

    var filteredTable = table.Clone();

    filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));

    return filteredTable;
}