You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中简洁筛选DataTable?处理VoidDate列筛选场景

问题解答

核心选择:复制后筛选更安全

直接修改原DataTable存在潜在风险——如果该DataTable还被其他代码引用,删除行的操作会意外影响其他逻辑。因此优先复制一份新的DataTable再执行筛选,避免产生副作用。

简洁实现方式

方法1:利用DataView.RowFilter(传统DataTable操作风格)

这种方式代码简洁,借助DataView的过滤能力生成新表:

public static DataTable GetInvoicesDataTable(string checkNo, int assocBankAcctID,
    int assocAcctLedgerID, int actionItemID, bool fetchAllItems, bool isUnvoid)
{
    string sql = string.IsNullOrEmpty(checkNo) && !fetchAllItems
        ? GetSingleRecordQuery()
        : GetMultipleRecordQuery(checkNo, fetchAllItems);

    DataTable dt = DB.RtnTable(sql, DB.DB_CUSTOMER_DATA, assocBankAcctID, checkNo, actionItemID,
        assocAcctLedgerID);

    // 复制原表的结构与数据
    DataTable filteredDt = dt.Copy();
    
    if (isUnvoid)
    {
        // 保留VoidDate为null的行(排除非null记录)
        filteredDt.DefaultView.RowFilter = "VoidDate IS NULL";
    }
    else
    {
        // 保留VoidDate不为null的行(排除null记录)
        filteredDt.DefaultView.RowFilter = "VoidDate IS NOT NULL";
    }
    
    // 将过滤后的DataView转换为DataTable返回
    return filteredDt.DefaultView.ToTable();
}

方法2:使用LINQ查询(现代C#风格)

如果项目支持LINQ to DataSet,代码逻辑会更直观:

using System.Linq;
using System.Data;

public static DataTable GetInvoicesDataTable(string checkNo, int assocBankAcctID,
    int assocAcctLedgerID, int actionItemID, bool fetchAllItems, bool isUnvoid)
{
    string sql = string.IsNullOrEmpty(checkNo) && !fetchAllItems
        ? GetSingleRecordQuery()
        : GetMultipleRecordQuery(checkNo, fetchAllItems);

    DataTable dt = DB.RtnTable(sql, DB.DB_CUSTOMER_DATA, assocBankAcctID, checkNo, actionItemID,
        assocAcctLedgerID);

    IEnumerable<DataRow> filteredRows;
    if (isUnvoid)
    {
        filteredRows = dt.AsEnumerable().Where(row => row.IsNull("VoidDate"));
    }
    else
    {
        filteredRows = dt.AsEnumerable().Where(row => !row.IsNull("VoidDate"));
    }
    
    // 将筛选后的行集合转为新的DataTable
    return filteredRows.CopyToDataTable();
}

补充说明

  • 若能确保原DataTable不会被其他代码引用,也可直接修改原表(比如用dt.Rows.Remove批量删除不符合条件的行),但这种方式风险较高,不推荐。
  • LINQ方式在.NET Framework中需要添加System.Data.DataSetExtensions引用,.NET Core/.NET 5+版本默认包含该引用。

内容的提问来源于stack exchange,提问作者CarlosG90

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:23:34