2013-02-25 2 views
2

안녕하세요 저는 MS 101 linq 예제를 통해 자신의 길을 코딩하고 있습니다.Linq SelectMany

"JoinOperators"는 람다 구문에 대한 쿼리 식을 리팩터링하려고하고 있으며 그 반대의 경우도 마찬가지입니다.

어쨌든, 예를 105에 나는이 쿼리 식을 참조하십시오

var supplierCusts = 
    from sup in suppliers 
    join cust in customers on sup.Country equals cust.Country into cs 
    from c in cs.DefaultIfEmpty() // DefaultIfEmpty preserves left-hand elements that have no matches on the right side 
    orderby sup.SupplierName 
    select new 
    { 
     Country = sup.Country, 
     CompanyName = c == null ? "(No customers)" : c.CompanyName, 
     SupplierName = sup.SupplierName 
    }; 

을 그리고 람다으로이 방법을 구현하는 시도 : 나는 공급 업체에 액세스 할 수없는 몇 가지 이유를 들어

// something is not right here because the result keeps a lot of "Join By" stuff in the output below 
var supplierCusts = 
    suppliers.GroupJoin(customers, s => s.Country, c => c.Country, (s, c) => new { Customers = customers, Suppliers = suppliers }) 
     .OrderBy(i => i.Suppliers) // can't reference the "name" field here? 
     .SelectMany(x => x.Customers.DefaultIfEmpty(), (x, p) => // does the DefaultIfEmpty go here? 
      new 
      { 
       Country = p.Country, 
       CompanyName = x == null ? "(No customers)" : p.CompanyName, 
       SupplierName = p // not right: JoinOperators.Program+Customer ... how do I get to supplier level? 
      }); 

을 이 수준의 정보. 공급 업체를 통해 고객을 전환하면 고객 수준 정보에 액세스 할 수 없습니다.

두 개체의 필드 수준에서 끌어낼 수있는 SelectMany의 오버로드가 있습니까?

또한 GroupJoin이 2 개의 컬렉션 (공급 업체 및 고객)이있는 객체를 반환하는 것으로 보이는 이유를 알 수 없습니다. 어떻게 든 그들과 합류하지 않겠습니까?

나는 GroupJoin의 작동 방식을 이해하지 못한다고 생각합니다.

답변

5

당신은 가입 그룹에서 잘못된 결과 선택이 문제가 시작된 곳이 있습니다.

var supplierCusts = 
    suppliers 
    .GroupJoin(customers, 
       sup => sup.Country, 
       cust => cust.Country, 
       (sup, cs) => new { sup, cs }) 
    .OrderBy(x => x.sup.Name)  
    .SelectMany(x => x.cs.DefaultIfEmpty(), (x, c) => 
     new 
     { 
      Country = x.sup.Country, 
      CompanyName = c == null ? "(No customers)" : c.CompanyName, 
      SupplierName = x.sup.Name 
     }); 
+0

나는이 같은 쿼리를 시도 할 때마다, 나는 오류가 발생,는 " 'GroupJoin'작업이 컬렉션의 선택은 'DefaultIfEmpty'을 호출하는 'SelectMany'작업에 의해 따라야합니다 : 여기에 고정 된 쿼리입니다 방법." 그게 뭐야? – Boydski

+0

@Boydski는 이전에 그런 실수를 한 적이 없었습니다. 재현 할 단계가있는 문제로 문제를 게시 할 수 있습니까? –

+0

http://stackoverflow.com/questions/20336653/outer-join-with-linq-causing-groupjoin-error – Boydski

1

질의 표현식을 람다로 변환하는 법을 배우고 싶다면 LinqPad을 체크 아웃 해보세요. 기본적으로이를 수행 할 수 있습니다.

말했다되고 그건
Suppliers 
    .GroupJoin (
     Customers, 
     sup => sup.Country, 
     cust => cust.Country, 
     (sup, cs) => 
     new 
     { 
      sup = sup, 
      cs = cs 
     } 
    ) 
    .SelectMany (
     temp0 => temp0.cs.DefaultIfEmpty(), 
     (temp0, c) => 
     new 
     { 
      temp0 = temp0, 
      c = c 
     } 
    ) 
    .OrderBy (temp1 => temp1.temp0.sup.CompanyName) 
    .Select (
     temp1 => 
     new 
     { 
      Country = temp1.temp0.sup.Country, 
      CompanyName = (temp1.c == null) ? "(No customers)" : temp1.c.CompanyName, 
      SupplierName = temp1.temp0.sup.CompanyName 
     } 
    ) 

, 나는 일반적으로 코드와 쿼리 구문 대신 람다 구문을 사용하여 더 쉽게 유지 관리 할 수 ​​SelectMany을 찾아 다음과 같이 예를 들어, 쿼리가 변환됩니다.

이 예제의 GroupJoin은 .DefaultIfEmpty 절을 통해 왼쪽 조인을 수행하는 데 사용됩니다.

1

이 시도 :

var supplierCusts = 
    suppliers.GroupJoin(customers, s => s.Country, c => c.Country, (s, c) => new { Supplier = s, Customers = c }) 
     .OrderBy(i => i.Supplier.SupplierName) 
     .SelectMany(r => r.Customers.DefaultIfEmpty(), (r, c) => new 
     { 
      Country = r.Supplier.Country, 
      CompanyName = c == null ? "(No customers)" : c.CompanyName, 
      SupplierName = r.Supplier.SupplierName 
     }); 
관련 문제