C# Linq 内连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1876304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:34:30  来源:igfitidea点击:

C# Linq Inner Join

c#linq

提问by Udana

I want to select the persons only who are having pets.

我只想选择养宠物的人。

when I execute the query

当我执行查询时

var query = from p in people
                        join
                        pts in pets
                        on p equals pts.Owner into grp
                        select new {grp=grp,PersonName=p.FirstName};

Person does not have pet also get selected.

没有宠物的人也被选中。

My Lists are

我的清单是

Person[] prn = new Person[3];
prn[0] = new Person();
prn[0].FirstName = "Jon";
prn[0].LastName = "Skeet";

prn[1] = new Person();
prn[1].FirstName = "Marc";
prn[1].LastName = "Gravell";

prn[2] = new Person();
prn[2].FirstName = "Alex";
prn[2].LastName = "Grover";

List<Person> people = new List<Person>();

 foreach (Person p in prn)
 {
     people.Add(p);
 }

 Pet[] pt = new Pet[3];

 pt[0] = new Pet();
 pt[0].Name = "Zonny";
 pt[0].Owner = people[0];

pt[1] = new Pet();
pt[1].Name = "Duggie";
pt[1].Owner = people[0];

pt[2] = new Pet();
pt[2].Name = "Zoggie";
pt[2].Owner = people[1];

List<Pet> pets=new List<Pet>();
 foreach(Pet p in pt)
 {
    pets.Add(p);
 }

采纳答案by Jon Skeet

That's because you're using join ... intowhich does a group join. You just want a normal join:

那是因为您正在使用join ... intowhich 进行组加入。你只想要一个正常的加入:

var query = (from p in people
             join pts in pets on p equals pts.Owner
             select p).Distinct();

Alternatively, if you want the people with pets, and their owners, you could do something like:

或者,如果您想要养宠物的人和他们的主人,您可以执行以下操作:

var query = pets.GroupBy(pet => pet.Owner)
                .Select(x => new { Owner = x.Key, Pets = x.ToList() });

That will give a result where you can get each owner and their pets, but only for people who havepets.

这将产生一个结果,你可以得到每个主人和他们的宠物,但仅限于宠物的人。

If you want something else, let us know...

如果您想要其他东西,请告诉我们...

By the way, now would be a good time to learn about object and collection initializers. Here's a simpler way to initialize your peoplelist, for example:

顺便说一下,现在是学习对象和集合初始值设定项的好时机。这是初始化people列表的更简单方法,例如:

List<Person> people = new List<Person>
{
    new Person { FirstName = "Jon", LastName = "Skeet" },
    new Person { FirstName = "Marc", LastName = "Gravell" },
    new Person { FirstName = "Alex", LastName = "Grover" },
};

Much more compact :)

更紧凑:)

EDIT: A cross join is easy:

编辑:交叉连接很容易:

var query = from person in people
            from pet in pets
            select new { person, pet };

Left joins are effectively emulated using group joins. As it sounds like you've got C# in Depth, I suggest you read chapter 11 thoroughly :)

使用组连接可以有效地模拟左连接。听起来你已经深入了解了 C#,我建议你彻底阅读第 11 章 :)

回答by Mark Byers

Here's a different way to do it, adding only one line:

这是一种不同的方法,只添加一行:

var query = from p in people
            join pts in pets
            on p equals pts.Owner into grp
            where grp.Any()             // <--- added this
            select new {grp=grp,PersonName=p.FirstName};

Here I select the groups, as you do, but I added one line that selects only the groups that contain at least one element, and ignore the rest.

在这里,我像您一样选择组,但我添加了一行,仅选择包含至少一个元素的组,而忽略其余的组。

回答by tt83

this can also be done using lambda expressions in a single line of code...

这也可以在一行代码中使用 lambda 表达式来完成...

IEnumerable<Person> peopleWithPets = people.Where(x => pets.Any(y => y.Owner == x));