Linq选择两个属性Distinct

时间:2012-04-13 20:09:38

标签: c# linq linq-to-entities distinct

我有一个相当复杂的LINQ查询,它连接几个表,并选择一个新的匿名类型,它是三个IEnumerable的{Users, JobProviders, Jobs}。它返回一个IQueryable来维护延迟执行,从而消除了来自this question的DistintBy。

其中一列是排名,我需要确保只选择每个作业(另一列,许多作业将被选中)排名最低的记录。区别不起作用,因为排名显然会使行唯一。

我认为group子句可能对此有所帮助,但它将返回类型更改为IGrouping。我不完全理解小组是如何工作的,所以我可能错了,但看起来它不会起作用。对于每项工作有没有办法说,只采取最低级别?

类似

let jobRank = JobProvider.Rank
...where min(rank)

2 个答案:

答案 0 :(得分:4)

你可以使用分组,因为它让我畏缩使用groupBy做一个独特的。您只需拨打First上的IGrouping即可获得该群组中的一个项目,这实际上是一个独特的项目。它看起来像这样:

var distinctItems = data.GroupBy(item => new{
  //include all of the properties that you want to 
  //affect the distinct-ness of the query
  item.Property1
  item.Property2
  item.Property3
})
.Select(group => group.Key);
//if it's important that you have the low rank use the one below.
// if you don't care use the line above
//.Select(group => group.Min(item => item.Rank));

答案 1 :(得分:2)

这里的解决方案很好:

LINQ's Distinct() on a particular property

你需要的是有效的“明显的”。我不相信它是LINQ的一部分,尽管写起来相当容易:

What you need is a "distinct-by" effectively. I don't believe it's part of LINQ as it stands, although it's fairly easy to write:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
    (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (seenKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}