【问题标题】:Splitting a Datatable based on Column value根据列值拆分数据表
【发布时间】:2015-06-18 11:07:03
【问题描述】:

我有一个包含 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] 时,我得到:

"索引超出范围。必须为非负数且小于大小 的集合。参数名称:索引"

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

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

【问题讨论】:

  • 尚不清楚为什么您展示的方法不起作用。结果List&lt;DataTable&gt;。所以第一个表是result[0],第二个表是result[1]。它永远不会包含超过两个表。
  • 您的意思是表的顺序不正确 - 您可以订购 linq 查询。
  • 我的意思是当我尝试访问结果[0]时,我得到了预期的缩短的结果列表。当我点击结果 [1] 时,我得到“索引超出范围。必须为非负数且小于集合的大小。参数名称:索引”
  • @Spitfire2k6:只有当列表仅包含一个表并且行具有所有相同的列值时才会出现该异常。

标签: c# list datatable


【解决方案1】:

考虑到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();

【讨论】:

  • 现在这就是我所说的答案!干杯芽:D
  • 我有一个数据表,想按列数分成两半。请帮忙。 stackoverflow.com/questions/31271259/…
  • @SearchForKnowledge,已在您的问题主题中发布了答案。看看有没有帮助。
【解决方案2】:

您的结果List&lt;DataTable&gt;。所以第一个表是result[0],第二个表是result[1]。它永远不会包含两个以上的表。

它可以包含

  • 如果源表为空,则为 0 个表
  • 如果所有表的值相同,则为 1 个表或
  • 如果两个值都包含,则为 2 个表。

来自您的评论:

当我尝试访问结果 [0] 时,我得到了预期的缩短列表 结果。当我点击结果 [1] 时,我得到“索引超出范围。必须是 非负数且小于集合的大小。参数名称: 索引”

如果列表仅包含一个表,并且仅当行具有所有相同的 column-a-value(f.e. all have 1)时,就会出现该异常。

但如果你愿意,你可以使用另一种方法。这使用了Lookup&lt;TKey, TValue&gt;:

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(创建一个具有相同列的空表)和Any-check,因为如果序列不包含行,CopyToDataTable 会引发异常。

【讨论】:

    【解决方案3】:
     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();
    

    【讨论】:

    • 请注意,如果查询没有返回任何行,CopyToDataTable() 将引发 The source contains no DataRows 异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多