2012-03-14 4 views
5

현재 LINQ의 기본 사항 중 일부를 이해하려고합니다. 나는 Netflix OData 소스를 쿼리하기 위해 LINQPad를 사용 해왔다.LINQ 람다 쿼리 '선택'이 oData와 작동하지 않습니다.

출처 : 람다 쿼리를 사용할 때 단일 속성을 선택할 수없는 것http://odata.netflix.com/v2/Catalog/

- 이해력 쿼리가 완벽하게 작동합니다. Netflix oData 소스에서 lambdas를 사용하여보다 복잡한 쿼리를 수행하는 코드 단편을 발견했습니다.이 코드는 엔티티의 한 속성을 반환하는 데는 문제가 없습니다.

// works fine 
var compQuery = from t in Titles 
       where t.ReleaseYear == 2007 
       select new { t.Name }; 
compQuery.Dump(); 



// fails: "Can only specify query options (orderby, where, take, skip) after last navigation." 
var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => t.Name); 

lambdaQuery.Dump(); 


// works fine - found on SO. 
var lambdaQuery2 = People 
    .Expand("TitlesActedIn") 
    .Where(p => p.Name == "George Lucas") 
    .First() 
    .TitlesActedIn.Select(t => t.ShortName);    

lambdaQuery2.Dump(); 

사람은 기본 람다 쿼리 할 때 하나 개의 속성을 반환하도록 요청 실패 이유에 도움이 되거 수 있을까요?

답변

4

이 실제로 동일합니다 것입니다 this- 첫 번째 시도에서 하나를

// fails: "Can only specify query options (orderby, where, take, skip) after last navigation." 
var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => new { t.Name }); 

lambdaQuery.Dump(); 
+0

아아아, 이제 시도해 보았습니다! - 내가 이해하지 못하는 것은 어떻게 다른 람다 쿼리 (사람들)가 투영을 위해 익명의 타입을 생성 할 필요가 없다는 것입니까? – Dal

+0

결과를 구체화하는'.First()'를 호출하기 때문에 전체 레코드를 제거한 다음 클라이언트의 메모리에있는 속성을 선택합니다. –

+0

왜 익명 유형을 사용해야하는지 설명해 주시겠습니까? 감사합니다. –

12

중 하나로, OData이 속성에 투사 지원하지 않습니다 - 당신이 생각 해결할 수 있습니다

var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(x=> new { x.Name }) 
      .AsEnumerable() 
      .Select(t => t.Name); 

AsEnumerable()을 사용하면 투영이 잘 작동하는 (OData 쿼리 대신) Linq-to-Objects 컨텍스트에서 쿼리의 마지막 부분을 강제로 실행합니다. 주어진 답변을 사용

+0

고마워, 그 작품 - 내가 여기 AsEnumerable에 관한 좀 더 많은 정보를 찾았 어 - http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/d427cbf6-4d8a-42ee-9799-d5ca79e581dc – Dal

+0

나는 이것을 작업에서 테스트 할 수 있었으면 좋겠지 만 (Netflix는 여기에서 차단되었습니다.) 실제로 필요한 첫 번째 프로젝션입니까? 여기에 약간 중복 된 것 같습니다. –

+0

@JeffMercado : Odata에 따르면 (그리고 위의 주석에있는 링크) odata 투영은 엔티티 자체를 보내지 만 불필요한 속성은 생략하므로 성능을 높이기 위해이 속성을 그대로 두는 것이 가장 좋습니다. 유선을 통과하는 데이터 – BrokenGlass

0

, 나는 몇 가지 테스트를 실행 및 실행 시간에 관한 몇 가지 흥미로운 것들을 발견 :

// Avg Execution Time: 5 seconds 
var query1 = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => new {t.Name});  
query1.Dump(); 


// Avg Execution Time: 15 seconds 
var query2 = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .AsEnumerable() 
      .Select(t => t.Name);  
query2.Dump(); 

그래서 바로 질의 1에 생각에 나는 오전을, 단지 '이름'속성이 반환되고 ? 쿼리 2에서 'AsEnumerable()'메서드는 모든 속성 값을 갖는 엔터티를 반환하므로 실행 시간이 길어 집니까?

+0

그렇습니다. 전송 된 데이터는 query2에서 훨씬 더 커집니다. 또한 전체 엔터티를 쿼리 할 때 상황에 따라 변경 내용을 추적하므로이 데이터가 훨씬 커집니다. – springy76

관련 문제