如何使用LINQ从DataTable获取唯一列

时间:2014-03-07 19:08:23

标签: c# linq datatable

我在C#中有一个DataTable,其列定义如下:

DataTable dt = new DataTable();
dt.Columns.Add("OrgName", typeof(string));
dt.Columns.Add("OrgExId", typeof(string));
dt.Columns.Add("UserName", typeof(string));
dt.Columns.Add("UserExId", typeof(string));
dt.Columns.Add("UserEmail", typeof(string));

“UserName”,“UserExId”和“UserEmail”都是唯一的,它们按“OrgName”和“OrgExId”分组

我想写一个LINQ查询来创建一个包含唯一“OrgExId”和“OrgName's”的新DataTable

据我所知:

var results = from row in dt.AsEnumerable()
              group row by row["OrgExId"] into orgs
              select orgs;

特别是在这个查询中,我不明白我应该如何选择原始DataTable中的行。 Visual Studio说orgs是'IGrouping'类型,但我以前从未真正看过这种类型,也不确定如何操作它。

这是一个关键值对吗?

对此感到抱歉。我没有说明我的最终结果。

我希望最终得到一个DataTable,其中有两列,不同的是“OrgExId”和“OrgName”。 (“OrgExId”和“OrgName”之间存在一对一的关系)

3 个答案:

答案 0 :(得分:2)

你真正需要的是一个Distinct子句

    var output = dt.AsEnumerable()
        .Select(x => new {OrgExId = x["OrgExId"], OrgName = x["OrgName"]})
        .Distinct();

然后,您可以对此进行迭代并构建DataTable或您需要的任何内容。

更新:您要求输出为DataTable,上述解决方案并不适合我,因为它需要额外的工作。为了提高效率,您可以进行自定义相等比较。

你的linq看起来像这样......

    // This returns a DataTable
    var output = dt.AsEnumerable()
        .Distinct(new OrgExIdEqualityComparer())
        .CopyToDataTable();

你的比较器看起来像这样......

public class OrgExIdEqualityComparer : IEqualityComparer<DataRow>
{
    public bool Equals(DataRow x, DataRow y)
    {
        return x["OrgExId"].Equals(y["OrgExId"]);
    }

    public int GetHashCode(DataRow obj)
    {
        return obj["OrgExId"].GetHashCode();
    }
}

答案 1 :(得分:1)

使用Key的{​​{1}}属性:

IGrouping

它将为您提供匿名类型的集合。要获得var results = from row in dt.AsEnumerable() group row by new { row.GetField<string>("OrgExId"), row.GetField<string>("UserName") } into orgs select orgs.Key; ,您只需iterate over results and add it into DataTable即可。

答案 2 :(得分:0)

    DataTable dt = new DataTable();
    dt.Columns.Add("OrgName", typeof(string));
    dt.Columns.Add("OrgExId", typeof(string));
    dt.Columns.Add("UserName", typeof(string));
    dt.Columns.Add("UserExId", typeof(string));
    dt.Columns.Add("UserEmail", typeof(string));

    // put some data for testing purpose

    var id = Guid.NewGuid().ToString();
    for (var i = 0; i < 10; i++)
            dt.Rows.Add(id, i.ToString(), "user_name", Guid.NewGuid().ToString());

    var x = dt.Rows.Cast<DataRow>().Select(x => x.Field<string>("UserName")).Distinct();

    Console.WriteLine(x);