使用Linq基于2个字段获取List中的重复条目列表

时间:2014-09-02 19:24:46

标签: c# linq group-by

我正在使用以下Linq来确定在某些自定义验证期间我的列表中是否有任何无效条目 - 我想知道是否有任何人根据他们工作的公司被分配了相同的号码,其工作正常:< / p>

var duplicates = Persons.GroupBy(x => 
                new { x.Number, x.CompanyId}, (key) => new { key.Number, key.CompanyId })
                .Where(y => y.Count() > 1);

对于一个简单的Person类:

class Person
{
    public string Name { get; set; }
    public int Number { get; set; }
    public int CompanyId { get; set; }
}

建立一些测试数据:

List<Person> Persons = new List<Person>();
// add people (users would do this!)
Persons.Add(new Person() { Name = "Person 1", Number = 1, CompanyId = 1 }); // invalid
Persons.Add(new Person() { Name = "Person 2", Number = 2, CompanyId = 1 });
Persons.Add(new Person() { Name = "Person 3", Number = 3, CompanyId = 1 });
Persons.Add(new Person() { Name = "Person 4", Number = 1, CompanyId = 1 }); // invalid
Persons.Add(new Person() { Name = "Person 5", Number = 2, CompanyId = 2 }); // invalid
Persons.Add(new Person() { Name = "Person 6", Number = 2, CompanyId = 2 }); // invalid

检查是否有任何重复和处理:

var duplicates = Persons.GroupBy(x => 
                new { x.Number, x.CompanyId}, (key) => new { key.Number, key.CompanyId })
                .Where(y => y.Count() > 1);

if (duplicates.Any())
{
    // build a string
}

我想要做的是获取无效条目的列表并通知用户。所以在上面的例子中,我想输出以下文字:

  • 第1号公司和第4号人员被分配了相同的公司#1号码#1。
  • 第5号人员和第6人被分配了#2号公司的相同号码#2。

2 个答案:

答案 0 :(得分:1)

更改您的分组,按键返回名称作为选择和分组。 String.Join然后合并列表

var duplicates = Persons
    .GroupBy(key => new { key.Number, key.CompanyId }, a=>a.Name)
    .Where(y => y.Count() > 1);

var sb = new StringBuilder();
foreach (var duplicate in duplicates)
{
    sb.AppendLine(String.Format("{0} have been assigned the same Number {1} for Company #{2}",
                                String.Join(" and ", duplicate), duplicate.Key.Number,
                                duplicate.Key.CompanyId));
}
var message = sb.ToString();

现在检查消息是否为空,以确定您是否有重复项而不是Any()语句。

答案 1 :(得分:1)

我发现使用查询语法而不是流利语法正确编写LINQ查询分组更容易。这是一个查询,可以为您提供所需的字符串:

from p in Persons   
group p by new { p.Number, p.CompanyId } into g
where g.Count () > 1
select string.Format(
    "{0} have been assigned the same number #{1} for company {2}",
    string.Join(" and ", g.Select (x => x.Name)),
    g.Key.Number,
    g.Key.CompanyId);

请注意,该查询不能用作LINQ-to-SQL / Entities查询,它只能用于内存数据。