2009-02-08 5 views
41

확장 구문 사용 나는 두 개의 목록에서 LINQ를 사용하여 왼쪽 조인을 만들려고합니다. 다음은 Microsoft의 도움을 받았지만 애완 동물 목록에 요소가 없음을 보여주기 위해 수정했습니다. 내가 끝내고있는 것은 0 요소의 목록입니다. 나는 내부 조인이 일어나기 때문이라고 생각합니다. 내가 끝내고 싶은 것은 누락 된 요소에 null 데이터가 채워진 3 개의 요소 (3 Person 개체) 목록입니다. 즉 왼쪽 - 결합. 이것이 가능한가?LINQ 내부 조인 대 왼쪽 조인

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

답변

71

물건에 대답 안하면 당신은 선택의 발현 함께 놀러해야 할 수 있습니다 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(); 

를 사용해야합니다. 나는 당신에게 일대일 관계가있는 경우에 당신이 원하는 것을 원한다고 확신하지 못합니다.

내가는 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(); 
+1

여행 애호가 : 정확히 나는 무엇을 찾고 있었습니까! – Ekaterina

+0

질의 메소드에 대괄호를 달아서 .ToList()를 얻을 수 있는지 알지 못했습니다. 고마워요! – Haroon

+2

LINQ 선언적 쿼리 구문 "LINQ 구문"을 호출하지 마십시오. 둘 다 "LINQ 구문"입니다. 적절한 이름 지정은 : 조회 구문; vs : 메소드 구문;입니다. http://msdn.microsoft.com/en-us/library/bb397947.aspx – Pluc

2

LINQ의 왼쪽 조인은 DefaultIfEmpty() 메서드를 사용하여 수행 할 수 있습니다. 나는 사실 그냥 작동 수있는 쿼리 pets.DefaultIfEmpty()에 애완 동물을 변경하면 내 생각

...

편집을하지만 귀하의 경우에 대한 정확한 구문이없는 : 정말 때 그 말 ... 당신이 확장 방법을 사용하려면 내 생각

15

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 
+0

감사합니다 Gishu - 매우 유용한 정보. – Guy

+0

두 줄을 바꿀 수 있다고 생각합니다 :'join pet ...'와'ownedPet ... '를 단 한 줄로 바꾸십시오 :'from pet in pets.Where (x => person.Name == x.Owner. 이름) .DefaultIfEmpty()' –

5

나는이 같은 문제에 직면 다음과 같은 오류 메시지가 :

조인 절에 표현 중 하나의 유형이 잘못되었습니다. '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 

(...) 당신이 실제로 데이터베이스가있는 경우

+0

+1. 나는 같은 코드를 가진 2 개의 익명 클래스가 왜 같지 않은지 이해하려고 15 분 동안 코드를 쳐다 보았다. 그런 다음 명시 적 속성 이름을 추가했습니다 ... – drdwilcox

0

, 이것은 가장 간단한 방법입니다 :

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