我在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”之间存在一对一的关系)
答案 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);