Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq中的Distinct仅基于表的一个字段_C#_Sql_Linq - Fatal编程技术网

C# Linq中的Distinct仅基于表的一个字段

C# Linq中的Distinct仅基于表的一个字段,c#,sql,linq,C#,Sql,Linq,我正在尝试使用Linq中的.distinct来获得基于表的一个字段的结果,所以不需要表中的整个重复记录 我知道使用distinct编写基本查询,如下所示: var query = (from r in table1 orderby r.Text select r).distinct(); 但我需要不重复r.text的结果。尝试以下方法: table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault()); table1.Grou

我正在尝试使用Linq中的.distinct来获得基于表的一个字段的结果,所以不需要表中的整个重复记录

我知道使用distinct编写基本查询,如下所示:

var query = (from r in table1
orderby r.Text
select r).distinct();
但我需要不重复r.text的结果。

尝试以下方法:

table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());
table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());
这将按文本对表进行分组,并使用每组中的第一行,从而生成文本不同的行

但我需要的结果是r.text不重复

听起来好像你想要这个:

table1.GroupBy(x => x.Text)
      .Where(g => g.Count() == 1)
      .Select(g => g.First());
这将选择文本唯一的行。

Morelink有一种方法可以使用:

它将允许您执行以下操作:

var results = table1.DistictBy(row => row.Text);
缺少参数验证的方法的实现如下所示:

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;
        }
    }
}

围绕这个话题有很多讨论

您可以找到其中一个:

最流行的建议之一是@Servy所指出的将lambda表达式作为参数的独特方法


C的首席架构师Anders Hejlsberg提出了解决方案。还解释了为什么框架设计团队决定不添加带lambda的Distinct方法重载。

您可以尝试以下方法:table1.GroupByt=>t.Text.Selectshape=>shape.r.Distinct

根据我的发现,你的查询基本上是正确的。只需将select r更改为select r。文本就是全部,这将解决问题。这就是MSDN记录其工作原理的方式

例:

上面的答案导致实体框架出现System.NotSupported异常。对于实体框架,它必须是:

请尝试以下代码:

table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());

您需要指定要区分的字段,请参见抱歉,我不想使用equalityComparer。@MeghaJain,不管怎样,都将使用一个字段,因为GroupBy也需要一个字段。如果没有提供EqualityComparer,这两种方法都将使用默认的EqualityComparer。如果我错了,请纠正我,但这里的区别是在内存中完成的,而不是在DB中?这难道不能导致意外的完全扫描吗?@Kek。不,由于收益率回报,您将在第一个不同的元素处停止。最终,是的,您将把每个键加载到HashSet中,但是由于它是IEnumerable in和IEnumerable out,所以您将只获得这些项。如果您谈论的是LINQ to SQL,那么是的,这将进行表扫描。如果groupby有多个字段怎么办?@user585440:在这种情况下,您使用的匿名类型如下:table1.GroupByx=>new{x.Text,x.Property2,x.Property3}。选择x=>x.First;是的,你说得对,我已经找到了。无论如何,谢谢你。我还发现Selectx=>x.First会导致崩溃。最好更改为Selectx=>x.FirstOrDefault;我必须使用FirstOrDefault,否则会有运行时error@TruthOf42那不太可能。GroupBy不会创建空组,请参阅我之前的评论。很可能,您的代码包含的内容比您在此处看到的内容更多。可能您还有一个Where或第一个条件。您更改了select语句,这在本例中可能不需要
data.Select(x=>x.Name).Distinct().Select(x => new SelectListItem { Text = x });
table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());