根据列值拆分数据表

Splitting a Datatable based on Column value

我有一个包含 Bool(bit) 列的数据表。

  a         b
------    ------ 
  1         10
  0         20
  1         30
  0         20
  1         10 

我希望根据这个值(a 列)将其拆分为 2 个可独立排序的数据表

我看了看,发现了一个老问题:

Split a DataTable into 2 or more DataTables based on Column value

哪个给了这个:

List<DataTable> result = myDataTable.AsEnumerable()
        .GroupBy(row => row.Field<Boolean>("a"))
        .Select(g => g.CopyToDataTable())
        .ToList();

但结果不是我可以使用 result[0]result[1] 引用的数据表列表,就像我预期的那样。

当我点击 result[1] 时,我得到:

"Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

我想添加一条评论来询问,但该帖子已经超过 2 年了,恐怕我不会得到回复。

任何人都可以建议使用此代码或新的代码来实现我需要的方法吗?

你的结果一个List<DataTable>。所以第一个table是result[0],第二个table是result[1]。它永远不会包含两个以上的 table。

可以包含

  • 0 tables 如果源-table 为空
  • 1 table 如果所有值都相同或
  • 2 tables 如果两个值都包含。

来自您的评论:

When I try to access results[0] I get the expected shortened list of results. When I hit results [1] I get "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

如果列表仅包含一个 table,并且只有当行具有相同的列值(f.e。全部为 1)时才会出现这种情况。

但如果需要,您可以使用其他方法。这使用 Lookup<TKey, TValue>:

var aColLookup= myDataTable.AsEnumerable().ToLookup(row => row.Field<int>("a"));

DataTable trueTable = myDataTable.Clone();
DataTable falseTable = myDataTable.Clone();
if(aColLookup[1].Any())
    trueTable = aColLookup[1].CopyToDataTable();
if (aColLookup[0].Any())
    falseTable = aColLookup[0].CopyToDataTable();

我必须使用 Clone(创建一个具有相同列的空 table)和 Any-check 因为如果序列包含 CopyToDataTable 会抛出异常没有行。

考虑到 dt 数据表包含包括两列的所有记录,您可以创建两个 DataView 并使用您的过滤条件

EnumerableRowCollection<DataRow> query =
    from data in dt.AsEnumerable()
    where data.Field<bool>("a") == true 
    select data;

DataView view1 = query.AsDataView();



EnumerableRowCollection<DataRow> query1 =
    from data in dt.AsEnumerable()
    where data.Field<bool>("a") == false 
    select data;

DataView view2 = query1.AsDataView();
 Globals.Productsdt = Pfdt.AsEnumerable()
                                            .Where(r => r.Field<string>("basecurve") == PFlist[j].PFBC.ToString())
                                            .Where(r => r.Field<string>("diameter") == PFlist[j].PFDM.ToString())
                                            .CopyToDataTable();