简体   繁体   English

如何在C#中将不同应用于LINQ查询?

[英]How to apply distinct to linq query in c#?

I have this query 我有这个查询

from d in db.v_Report_CompanySearches
where d.PersonName.ToLower().Contains(mPersonName)
orderby d.PersonName ascending
group d by d.PersonName into g
select (g);

But it returns all columns, when I just want PersonName . 但是当我只想要PersonName时,它返回所有列。 Plus I want to make sure PersonName is distinct, right now it returns duplicate values. 另外,我想确保PersonName是不同的,现在它返回重复的值。

What is wrong here? 怎么了

Call Dictinct at the end of query using parenthesis, you don't need the grouping thing there. 在查询末尾使用括号调用Dictinct ,您无需在此处进行分组。

var result  = (from d in db.v_Report_CompanySearches
               where d.PersonName.ToLower().Contains(mPersonName)
               orderby d.PersonName ascending
               select d.PersonName ).Distinct();

original question: Is there way to use Distinct in LINQ query syntax? 原始问题: 有没有办法在LINQ查询语法中使用Distinct?

accepted answer: 接受的答案:

The Distinct extension method in LINQ does not have a query syntax equivalent. LINQ中的Distinct扩展方法没有等效的查询语法。

See http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx for additional information as to why. 有关原因的其他信息,请参见http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx

answer #2 答案2

There is no Distinct() method syntax in the language integrated query syntax. 语言集成查询语法中没有Distinct()方法语法。 The closest you could do would be to move the current call: 您能做的最接近的是移动当前通话:

 var q = (from c in tbl select c.TABLE_TYPE).Distinct(); 

Use g.First() 使用g.First()

from d in db.v_Report_CompanySearches
where d.PersonName.ToLower().Contains(mPersonName)
orderby d.PersonName ascending
group d by d.PersonName into g
select (g.First().PersonName);

Use select (g.key) to select the grouping key only. 使用select (g.key)仅选择分组键。

from d in db.v_Report_CompanySearches
where d.PersonName.ToLower().Contains(mPersonName)
orderby d.PersonName ascending
group d by d.PersonName into g
select (g.Key);

in your case the result will be an Enumerable<string> assuming PersonName is a string. 在您的情况下,假设PersonName是字符串,结果将是Enumerable<string>

If you use the g.First() method as proposed by another answer, the result will be an IEnumerable<CompanySearch> assuming db.v_Report_CompanySearches is a list of CompanySearch . 如果您使用另一个答案建议的g.First()方法,则假定db.v_Report_CompanySearchesCompanySearch的列表,结果将是IEnumerable<CompanySearch> The result will contain only distinctive values for the PersonName but the other fields are just filled with the first match. 结果将仅包含PersonName的唯一值,但其他字段仅填充第一个匹配项。

If you just select(g) the result is an Enumerable<IGrouping<string, CompanySearch>> The result will contain the Personnames distinctive as a key (since you group by them) but contains all the results as values. 如果仅select(g)则结果为Enumerable<IGrouping<string, CompanySearch>>该结果将包含与众不同的Personnames作为键(因为您按它们分组),但将所有结果都包含为值。 (You can extract them by using a SelectMany statement, see How to get values from IGrouping ). (您可以使用SelectMany语句提取它们,请参阅如何从IGrouping获取值 )。

Since my answer got downvoted I make another example, everyone can execute and check the validiy of it: 由于我的答案被否决了,因此我举一个例子,每个人都可以执行并检查其有效性:

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public override string ToString()
    {
        return $"{Name}: {Age}";
    }
}

static void Main(string[] args) {
    personList = new List<Person>()
    {
        new Person {Name = "Jay", Age = 25},
        new Person {Name = "Hans", Age = 25},
        new Person {Name = "Fritz", Age = 25},
        new Person {Name = "Hello", Age = 26},
        new Person {Name = "World", Age = 27},
        new Person {Name = "Whatever", Age = 26},
        new Person {Name = "ASDF", Age = 24},
        new Person {Name = "Foo", Age = 25},
        new Person {Name = "Bar", Age = 22},
    };
    var ages = from p in personList
               where p.Age > 22
               orderby p.Age ascending
               group p by p.Age into g
               select (g);

    Console.WriteLine($"select(g): {ages.GetType()}");

    var ages2 = from p in personList
        where p.Age > 22
        orderby p.Age ascending
        group p by p.Age into g
        select (g.First());

    Console.WriteLine($"select(g.First()): {ages2.GetType()}");

    var ages3 = ages.First();
    Console.WriteLine($"(select(g)).First(): {ages3.GetType()}");
}

In the output you can see that the first one is an IEnumerable<IGrouping<int,Person>> , the second output is an IEnumerable<Person> and the third one is an IGrouping<int,Person> . 在输出中,您可以看到第一个是IEnumerable<IGrouping<int,Person>> ,第二个输出是IEnumerable<Person> ,第三个是IGrouping<int,Person>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM