2009-06-04 6 views
16

우리는 최근에 LINQ와 Object 간의 의미에서 주로 LINQ로 많은 작업을 해왔습니다. 유감스럽게도 검색어 중 일부는 약간 복잡 할 수 있습니다. 특히 여러 시퀀스를 조합하여 사용하기 시작하면 더욱 그렇습니다. 당신처럼 보이기 시작 쿼리를 얻을 때, 무슨 일을 정확히 알려 어려울 수 있습니다 :LINQ 쿼리 디버깅

IEnumerable<LongType> myCompanies =  relevantBusiness.Children_Companies 
      .Select(ca => ca.PR_ContractItemId) 
      .Distinct() 
      .Select(id => new ContractedItem(id)) 
      .Select(ci => ci.PR_ContractPcrId) 
      .Distinct() 
      .Select(id => new ContractedProdCompReg(id)) 
      .Select(cpcr => cpcr.PR_CompanyId) 
      .Distinct(); 

var currentNewItems = myCompanies 
       .Where(currentCompanyId => !currentLic.Children_Appointments.Select(app => app.PR_CompanyId).Any(item => item == currentCompanyId)) 
       .Select(currentId => new AppointmentStub(currentLic, currentId)) 
       .Where(currentStub=>!existingItems.Any(existing=>existing.IsMatch(currentStub))); 


Items = existingItems.Union(newItems).ToList(); 

등 등 ...

디버깅 경우에도, 말할 어려울 수 있습니다 누가 언제 무엇을하고 있는지. 불필요하게 "ToList"를 호출하여 시퀀스를 더 쉽게 조사 할 수있는 방법을 찾지 못하면 "복잡한"LINQ를 디버깅하는 방법에 대한 좋은 제안이 있습니까?

답변

13

이와 같은 쿼리는 적절한 데이터 구조를 선택하거나 작업을 캡슐화하고 분리하여 좋은 작업을 수행하지 못한다는 것을 나타내는 것으로 보입니다. 나는 그것을보고 그것을 분해하는 것이 좋습니다.

그러나 일반적으로 올바른 LINQ 쿼리를 디버깅하려면 하위 쿼리로 분해하고 디버거에서 한 번에 하나씩 결과를 검사하십시오.

+2

+1 LINQ 혼란을 리팩터링합니다. –

+0

진심으로 동의합니다. LinqToObjects를 사용하면 체인의 각 단계에서 실제로 작업하고 검사 할 객체를 얻을 수 있습니다. 식 평가가 끝날 때까지 지연되는 LinqToSQL과 달리 LinqToObjects의 확장 메서드는 다른 메서드와 마찬가지로 작동하며 즉시 평가됩니다. – tvanfosson

+1

LINQ to Object 쿼리는 Deferred 평가도 사용합니다. 하지만 디버깅하는 동안 그들을 평가할 수 있습니다. –

4

알고있는 도구에는 빌드가 없습니다. 가장 좋은 방법은 여러 하위 쿼리에서 쿼리를 분할하고 디버깅하는 동안 이러한 하위 쿼리를 평가하는 것입니다. 좋은 타사 도구는 LINQPad입니다.

3

This blog post에는 LINQ to Object를 디버깅하는 데 매우 유망한 기술이 있습니다.

13

내 대답은 늦게 "조금"알아,하지만 난이 공유 할 수 있었다 :

그냥 LinqPad를 발견하고는 (무료 언급하지 않기 위하여) 놀라운.
나는이 도구에 대해 알지 못해 오랫동안 Linq를 작성했다고 생각하지 않는다.

내가 이해하는 한, O'Reilly의 "C# 3.0 in a Nutshell""C# 4.0 in a Nutshell"의 저자 (s?)의 작품입니다.

8

매우 비슷한 질문에 대한 답변을 최근에 둘러 보았을 때 나는 여기 저기에 흥미로운 힌트를 발견했지만 그 질문에 답하는 것을 응집 된 이야기로 보지 않았습니다. 그래서 나 자신을 썼고 Simple-Talk.com (LINQ Secrets Revealed: Chaining and Debugging)에 게시되었습니다. 기사를 읽으려면 등록해야합니다 (사이트는 최근 몇 일 동안 변경된 것으로 보입니다). 기사의 주요 내용은 다음과 같습니다.

(1) LINQPad : 특별한 Dump() 메소드를 사용하십시오. LINQ 체인의 하나 이상의 지점에서이를 주입하여 데이터를 놀라운 깨끗하고 선명한 방식으로 시각화 할 수 있습니다.

(2) Visual Studio의 경우 : LINQ 체인 중간에 nop 문을 포함하여 중단 점을 설정할 수 있습니다. 참고 Visual Studio에서 중단 점을 설정하려면 return 문을 자체 줄에 있어야합니다. (이 팁 에릭 화이트의 블로그 항목 Debugging LINQ Queries 감사합니다.)

.Select(z => 
{return z;} 
) 

(3) Visual Studio에서 : 나는 기록 할 수 있도록 내 문서에서 제시 덤프() 확장 메서드 호출을 주입한다. 그의 유익한 기사 LINQ to Objects – Debugging에서 Bart De Smet의 Watch() 메소드를 시작하고 LINQPad의 Dump 출력과 비교하여 시각화를 향상시키기 위해 레이블과 색상을 추가했습니다.

(4) 마지막으로, LINQPad의 시각화 기능을 Robert Ivanc의 LINQPad Visualizer 추가 기능을 사용하여 Visual Studio로 가져올 수 있습니다 (예 : LINQPad의 Dump 메서드가 마음에 듭니다). 완벽한 솔루션이 아닙니다 (아직 VS2010에 대한 지원이 없으며 클래스가 직렬화 가능해야하며 일부 렌더링 문제가 필요합니다). 그러나 매우 유용합니다.

2016년 12월 1일 업데이트 그냥 Simple-Talk.com에 게시 된

는 위 기사의 속편이다 LINQ Debugging and Visualization. 이 기사에서는 Visual Studio 2015 용 OzCode 확장의 새로운 LINQ 디버깅 기능에 대해 자세히 설명합니다. OzCode는 결국 LINQ 디버깅을 쉽고 강력하게 만듭니다. (그리고, 아니, 나는 이 아니라가 OzCode에서 작동합니다 :-).

+0

잘 알고있는 기술! – GWLlosa

+1

이제 비주얼 라이저는 vs2010과 직렬화 할 수없는 클래스를 모두 지원합니다! :) –

+0

좋은 대답! – menkow

2

말 사과!

ReSharper에서 (나는 좋아한다) 나는이

initialObservations.Where(observation => observation.IsValid() && !observation.IsStationOnly).ToList(); 

예치가 섹시하고 매끄러운입니다하지만 그것을 통해 스테핑과 디버깅이

foreach (BomObservation initialObservation in initialObservations) 
{ 
    if(initialObservation.IsValid() && !initialObservation.IsStationOnly) 
     mappableObservations.Add(initialObservation); 
} 

를 변경 제안? 당신은 단지 그것을 할 수 없습니다. 나는 이것을 위해 foreach로 돌아갈 것이다.

나는 LinqPad도 좋아하는데, Linq는 '모든 것을 지배하기위한 하나의 고리'에서 꽤 멋지다고 생각 하긴하지만,이 시나리오에서 나는 무언가를 잃는다.