【问题标题】:Group a DataTable into separate DataTables?将数据表分组到单独的数据表中?
【发布时间】:2014-01-23 22:46:40
【问题描述】:

我有一个像这样的 DataTable -

EmpId,Country 
1,Germany
2,Germany
3,UK
4,UK
5,UK
6,France
7,USA
8,USA

我想按国家/地区分组并将所有组提取到单独的数据表中。所以,我们 将有 4 个组/数据表。我该怎么做?

Stackoverflow 不允许我粘贴完整的工作代码。所以就到这里了,谢谢 @Myles B. Currie

测试代码 -

public void main()
   {
        DataSet ds = (DataSet) Dts.Variables["obj_Rs"].Value;
        DataTable dt = ds.Tables[0];

        List<DataTable> allCountryTables = new List<DataTable>();

        DataView view = new DataView(dt);
        DataTable distinctValues = view.ToTable(true, "Country");

        //Create new DataTable for each of the distinct countries 
        //identified and add to allCountryTables list

        foreach (DataRow row in distinctValues.Rows)
        {
            //Remove filters on view
            view.RowFilter = String.Empty;
            //get distinct country name
            String country = row["Country"].ToString();
            //filter view for that country
            view.RowFilter = "Country = " + "'" + country + "'";
            //export filtered view to new datatable
            DataTable countryTable = view.ToTable();
            //add new datatable to allCountryTables 
            allCountryTables.Add(countryTable);
        }//for each

        foreach(DataTable tbl in allCountryTables){

            String table = getDataTable(tbl);
            MessageBox.Show(table);

        }//for
}//main


    public static string getDataTable(DataTable dt){

        string table = "";

        foreach (DataRow dataRow in dt.Rows)
        {
            foreach (var item in dataRow.ItemArray)
            {
                table = table + item.ToString() + "|";
            }//for

            table = table + Environment.NewLine;

        }//for

        return table;

    }//method

【问题讨论】:

  • 按美国分组,您是指按国家/地区分组吗?
  • @TimSchmelter - 是的,我指的是国家。现在解决这个问题。

标签: c# .net datatable .net-3.5


【解决方案1】:

当然不是执行此操作的最短方法,但既然您说您遇到 .Net 版本问题,那么完成这项工作还有很长的路要走。 (以下代码未经测试)

DataTable table; //Your Datatable
List<DataTable> allCountryTables = new List<DataTable>();

//Get distinct countries from table
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Country");

//Create new DataTable for each of the distinct countries identified and add to allCountryTables list    
foreach (DataRow row in distinctValues.Rows)
{
    //Remove filters on view
    view.RowFilter = String.Empty;
    //get distinct country name
    String country = row["Country"].ToString());
    //filter view for that country
    view.RowFilter = "Country = " + country;
    //export filtered view to new datatable
    DataTable countryTable = view.ToTable();
    //add new datatable to allCountryTables 
    allCountryTables.Add(countryTable);
}

【讨论】:

  • 谢谢。这似乎是唯一的出路。您的代码有一些更改。我将添加编辑后的代码作为答案。
  • 顺便说一句,您为什么要删除视图中的过滤器? view.RowFilter = String.Empty;不做会怎么样?
  • 顺便说一句,除了国家/地区之外,是否可以添加更多分组条件?
  • View 是在 foreach 循环范围之外定义的变量。当您对其应用过滤器时,您会减少视图中可见行的数量。如果您在添加新过滤器之前没有删除应用的过滤器,那么您的结果将只是适用于所有以前应用的过滤器的行。
  • 请通过添加更多分组条件来提供有关您的意思的更多详细信息。你的意思是你想要数据表,其中你有按 2 列分组的行,例如国家和用户名,还是您的意思是您只想按一列分组,但代码是动态的,您可以选择数据按哪一列分组?
【解决方案2】:

这应该可以完成工作:

var countryGroups = dataTable.AsEnumerable()
    .GroupBy(row => row.Field<string>("Country"));

请记住添加以下引用: System.Data.DataSetExtensions

【讨论】:

  • 即使在添加参考 System.Core.dll 并保存所有内容后,我也会收到错误消息 - 'System.Data.DataTable' 不包含 'AsEnumerable' 的定义并且没有扩展方法 'AsEnumerable' 接受可以找到“System.Data.DataTable”类型的第一个参数(您是否缺少 using 指令或程序集引用?)
  • 添加对 System.Data.DataSetExtensions 的引用应该可以完成这项工作
  • 我试过 tims 代码。添加参考 - System.Data.DataSetExtensions 后,我收到错误 - let 子句中的表达式类型不正确。调用“选择”时类型推断失败。你能帮我解决这个问题吗?
  • 抱歉,您使用的是我的代码还是 Tim Schmelter 的代码?
  • 我都想试试。您的代码是否需要更多行。我问是因为 tim 使用了更多的行。
【解决方案3】:

您可以使用 LINQ 为每个国家/地区创建数据表的子集:

Dim groups = From row In tblEmp
             Let country = row.Field(Of String)("Country")
             Group row By country Into Group
             Select Group.CopyToDataTable()
Dim allCountryTables = groups.ToList()

哎呀,我确定有一个 VB.NET 标记....

var groups = from row in tblEmp.AsEnumerable()
             let country = row.Field<string>("Country")
             group row by country into Group
             select Group.CopyToDataTable();
List<DataTable> allCountryTables = groups.ToList();

【讨论】:

  • 即使在添加参考 System.Core.dll 并保存所有内容后,我也会收到错误消息 - 'System.Data.DataTable' 不包含 'AsEnumerable' 的定义并且没有扩展方法 'AsEnumerable' 接受可以找到“System.Data.DataTable”类型的第一个参数(您是否缺少 using 指令或程序集引用?)
  • 在添加参考 - System.Data.DataSetExtensions 后,出现错误 - let 子句中的表达式类型不正确。调用“Select”时类型推断失败。
  • 嗯,我已经用你的样品表测试过了。 NET 4,我不知道 3.5 的问题是什么。对不起。
  • 我为此创建了一个问题 - stackoverflow.com/questions/21321761/…
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 2015-08-03
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 2020-03-28
  • 1970-01-01
相关资源
最近更新 更多