我试图在Linq中使用.distinct来获取基于表的一个字段的结果(因此不需要表中的整个重复记录).
我知道使用distinct来编写基本查询,如下所示:
var query = (from r in table1
orderby r.Text
select r).distinct();
Run Code Online (Sandbox Code Playgroud)
但我需要r.text不重复的结果.
Dan*_*rth 270
试试这个:
table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)
这将对表进行分组Text并使用每个组中的第一行,从而得到Text不同的行.
Ser*_*rvy 23
MoreLinq有一个DistinctBy方法,您可以使用:
它可以让你做到:
var results = table1.DistictBy(row => row.Text);
Run Code Online (Sandbox Code Playgroud)
该方法的实现(缺少参数验证)如下:
private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
foreach (TSource element in source)
{
if (knownKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*ter 12
但我需要r.text不重复的结果
听起来好像你想要这个:
table1.GroupBy(x => x.Text)
.Where(g => g.Count() == 1)
.Select(g => g.First());
Run Code Online (Sandbox Code Playgroud)
这将选择Text唯一的行.
小智 9
上面 Daniel Hilgarth的回答导致了Entity-Framework的System.NotSupported异常。使用Entity-Framework,它必须是:
table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)
从 .NET 6 开始,引入了新的DistinctBy运算符。然而,虽然这对于 Linq to Objects 效果很好,但似乎不适用于 Linq to Entities。我使用 EF Core 6.0.6 和 SQL Server 对其进行了测试。
一般来说,LINQ 运算符成对出现以支持这两种情况。例如,Enumerable.Select涵盖 Linq to Objects,Queryable.Select涵盖 Linq to Entities。
有趣的DistinctBy是,也有这两种风格,但 EF Core 的 SQL Server 提供程序不支持将其转换为 SQL。在我看来,原因是这会导致查询速度变慢。
围绕这个话题有很多讨论。
您可以在这里找到其中之一:
最流行的建议之一是采用 lambda 表达式作为参数的 Distinct 方法,正如 @Servy 所指出的。
C# 的首席架构师 Anders Hejlsberg在这里提出了解决方案。还解释了为什么框架设计团队决定不添加采用 lambda 的 Distinct 方法的重载。