当前位置:  开发笔记 > 编程语言 > 正文

LINQ Inner-Join vs Left-Join

如何解决《LINQInner-JoinvsLeft-Join》经验,为你挑选了3个好方法。

使用扩展语法我试图在两个列表上使用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 people = new List { magnus, terry, charlotte };
//List pets = new List { barley, boots, whiskers, daisy };
List pets = new List();

// 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();

tvanfosson.. 75

我想如果你想使用扩展方法,你需要使用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();

您可能必须使用选择表达式.我不确定在你有1对多关系的情况下,它会让你想要你想要的.

我认为使用LINQ Query语法会更容易一些

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();

请不要调用LINQ声明性查询语法"LINQ语法".它们都是"LINQ语法".正确的命名是"查询语法"与"方法语法".http://msdn.microsoft.com/en-us/library/bb397947.aspx (2认同)

后者的不正确命名是"yoda风格的语法". (2认同)


Gishu.. 17

您需要将连接的对象放入集合中,然后应用DefaultIfEmpty,因为JPunyon说:

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 people = new List { magnus, terry, charlotte };
List pets = new List{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


João Vieira.. 5

我遇到同样的问题时出现以下错误消息:

join子句中某个表达式的类型不正确.在对"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

(......)



1> tvanfosson..:

我想如果你想使用扩展方法,你需要使用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();

您可能必须使用选择表达式.我不确定在你有1对多关系的情况下,它会让你想要你想要的.

我认为使用LINQ Query语法会更容易一些

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();


请不要调用LINQ声明性查询语法"LINQ语法".它们都是"LINQ语法".正确的命名是"查询语法"与"方法语法".http://msdn.microsoft.com/en-us/library/bb397947.aspx
后者的不正确命名是"yoda风格的语法".

2> Gishu..:

您需要将连接的对象放入集合中,然后应用DefaultIfEmpty,因为JPunyon说:

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 people = new List { magnus, terry, charlotte };
List pets = new List{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



3> João Vieira..:

我遇到同样的问题时出现以下错误消息:

join子句中某个表达式的类型不正确.在对"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

(......)

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有