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
C# Linq Inner Join
提问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 ... into
which does a group join. You just want a normal join:
那是因为您正在使用join ... into
which 进行组加入。你只想要一个正常的加入:
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 people
list, 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));