LINQ Inner-Join与Left-Join

使用扩展语法我试图创build一个左连接使用两个列表上的LINQ我有。 以下是来自Microsoft的帮助,但我已经修改它显示宠物列表没有元素。 我最终得到的是0个元素的列表。 我认为这是因为内部连接正在发生。 我想要结束的是3个元素(3个Person对象)的列表,其中填充了缺失元素的空数据。 即一个左连接。 这可能吗?

Person magnus = new Person { Name = "Hedlund, Magnus" }; Person terry = new Person { Name = "Adams, Terry" }; Person charlotte = new Person { Name = "Weiss, Charlotte" }; //Pet barley = new Pet { Name = "Barley", Owner = terry }; //Pet boots = new Pet { Name = "Boots", Owner = terry }; //Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte }; //Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry, charlotte }; //List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy }; List<Pet> pets = new List<Pet>(); // Create a list of Person-Pet pairs where // each element is an anonymous type that contains a // Pet's name and the name of the Person that owns the Pet. var query = people.Join(pets, person => person, pet => pet.Owner, (person, pet) => new { OwnerName = person.Name, Pet = pet.Name }).ToList(); 

我想如果你想使用扩展方法,你需要使用GroupJoin

 var query = people.GroupJoin(pets, person => person, pet => pet.Owner, (person, petCollection) => new { OwnerName = person.Name, Pet = PetCollection.Select( p => p.Name ) .DefaultIfEmpty() } ).ToList(); 

你可能不得不玩弄selectexpression式。 我不确定在你有一对多关系的情况下它会给你想要的。

我认为LINQ查询语法更容易一些

 var query = (from person in context.People join pet in context.Pets on person equals pet.Owner into tempPets from pets in tempPets.DefaultIfEmpty() select new { OwnerName = person.Name, Pet = pets.Name }) .ToList(); 

你需要把连接的对象放到一个集合中,然后像JPunyon所说的那样应用DefaultIfEmpty:

 Person magnus = new Person { Name = "Hedlund, Magnus" }; Person terry = new Person { Name = "Adams, Terry" }; Person charlotte = new Person { Name = "Weiss, Charlotte" }; Pet barley = new Pet { Name = "Barley", Owner = terry }; List<Person> people = new List<Person> { magnus, terry, charlotte }; List<Pet> pets = new List<Pet>{barley}; var results = from person in people join pet in pets on person.Name equals pet.Owner.Name into ownedPets from ownedPet in ownedPets.DefaultIfEmpty(new Pet()) orderby person.Name select new { OwnerName = person.Name, ownedPet.Name }; foreach (var item in results) { Console.WriteLine( String.Format("{0,-25} has {1}", item.OwnerName, item.Name ) ); } 

输出:

 Adams, Terry has Barley Hedlund, Magnus has Weiss, Charlotte has 

当遇到同样的问题时,我遇到以下错误信息:

join子句中的一个expression式的types不正确。 types推断在调用“GroupJoin”失败。

解决了,当我使用相同的属性名称,它的工作。

(……)

 join enderecoST in db.PessoaEnderecos on new { CD_PESSOA = nf.CD_PESSOA_ST, CD_ENDERECO_PESSOA = nf.CD_ENDERECO_PESSOA_ST } equals new { enderecoST.CD_PESSOA, enderecoST.CD_ENDERECO_PESSOA } into eST 

(……)

Fabrice(LINQ in Action)的作者刚刚发表了一篇很好的博客文章,其中涵盖了我所问的问题中的材料。 我把它放在这里作为参考,因为这个问题的读者会觉得这有用。

将LINQ查询从查询​​语法转换为方法/操作符语法

使用DefaultIfEmpty()方法可以在LINQ中join左连接。 我没有你的情况确切的语法,虽然…

其实我想如果你只是改变宠物宠物.DefaultIfEmpty()在查询中可能工作…

编辑:我真的不应该回答事情,当它迟到…

如果你真的有一个数据库,这是最简单的方法:

 var lsPetOwners = ( from person in context.People from pets in context.Pets .Where(mypet => mypet.Owner == person.ID) .DefaultIfEmpty() select new { OwnerName = person.Name, Pet = pets.Name } ).ToList();