LINQ Inner-Join vs Left-Join

前端 未结 6 1100
轮回少年
轮回少年 2020-11-27 13:36

Using extension syntax I\'m trying to create a left-join using LINQ on two lists that I have. The following is from the Microsoft help but I\'ve modified it to show that the

相关标签:
6条回答
  • 2020-11-27 14:19

    Here's a good blog post that's just been posted by Fabrice (author of LINQ in Action) which covers the material in the question that I asked. I'm putting it here for reference as readers of the question will find this useful.

    Converting LINQ queries from query syntax to method/operator syntax

    0 讨论(0)
  • 2020-11-27 14:24

    Left joins in LINQ are possible with the DefaultIfEmpty() method. I don't have the exact syntax for your case though...

    Actually I think if you just change pets to pets.DefaultIfEmpty() in the query it might work...

    EDIT: I really shouldn't answer things when its late...

    0 讨论(0)
  • 2020-11-27 14:31

    If you actually have a database, this is the most-simple way:

    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();
    
    0 讨论(0)
  • 2020-11-27 14:32

    I think if you want to use extension methods you need to use the 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();
    

    You may have to play around with the selection expression. I'm not sure it would give you want you want in the case where you have a 1-to-many relationship.

    I think it's a little easier with the LINQ Query syntax

    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();
    
    0 讨论(0)
  • 2020-11-27 14:35

    You need to get the joined objects into a set and then apply DefaultIfEmpty as JPunyon said:

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

    Outputs:

    Adams, Terry              has Barley
    Hedlund, Magnus           has
    Weiss, Charlotte          has
    
    0 讨论(0)
  • 2020-11-27 14:36

    I the following error message when faced this same problem:

    The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.

    Solved when I used the same property name, it worked.

    (...)

    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
    

    (...)

    0 讨论(0)
提交回复
热议问题