C#Linq Inner Join

我想选择只有宠物的人。

当我执行查询

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[] 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 people = new List(); 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 pets=new List(); foreach(Pet p in pt) { pets.Add(p); } 

那是因为你正在使用join ... into群组加入。 你只想要一个普通的连接:

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

或者,如果您想要有宠物的人及其主人,您可以做以下事情:

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

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

如果您想要别的东西,请告诉我们……

顺便说一句,现在是了解对象和集合初始化器的好时机。 这是一种初始化people列表的简单方法,例如:

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

更紧凑:)

编辑:交叉连接很容易:

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

使用组连接有效地模拟左连接。 听起来你有深度C#,我建议你仔细阅读第11章:)

这是另一种方法,只添加一行:

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

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

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

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