2011-04-11 2 views
3

나는 LINQ 파워 유저가 아니지만 기본 수준에서 실수를 저지를 수 있습니다. LINQ가 쿼리 "전략"을 공식화하는 방법에 관한 질문이 있습니다. 나는 이것을 가능한 한 최선의 방법으로 설명하려고 노력할 것이고, 기억에 의해 극히 어리석은 예를 쓸 것이다.LINQ가 하나의 "조인"쿼리 대신 여러 쿼리 수행

여러 데이터베이스보기가 포함 된 데이터 모델이 있습니다. 의는 다음과 같이 뷰를 열 구조를 가지고 있다고 가정 해 봅시다 :

PersonView에게

PersonViewId | Surname | GivenName | OtherViewId 
------------------------------------------------ 

오더 뷰보기

OtherViewId | PersonViewId | Name 
--------------------------------- 

을보기위한 기본 키를 설정 한 후 (PersonView.PersonViewId/OtherView.OtherViewId) 및 해당 필드를 설정할 수 없도록 설정하면 PersonView.PersonViewId (Parent)와 OtherView.PersonViewId (Child) 간의 연결이 만들어집니다. 나는 그것이 "1-1"하고 그것을 소비하는 코드를 작성하도록 설정 : 매우 저조한 실적을 몰래 후

StringBuilder s = new StringBuilder(); 
foreach(PersonView p in dc.PersonViews) 
{ 
    s.AppendLine(p.OtherViews.Name + "<br />"); 
} 

을, 나는 데이터베이스를 프로파일과는 foreach 문에 PersonView의 각각에 대해 질의를하고 있었다 발견 성명서.

이 시점에서 쿼리를 다시 작성하고 DBML의 연결을 LINQ 쿼리의 JOIN으로 바꾸고 데이터베이스를 프로파일 링 한 다음 DB를 예상 한대로 한 번만 쿼리했습니다.

나는 그것이 DB와 ​​실제로 관련이 있다고 생각하지만, 실제로 DB를 쿼리하고 있지만 어디에 디버깅해야할지 모르겠다. 누군가가 이것을 사용하여 협회의 퍼포먼스를 향상시키는 데 도움이되도록 적절한 방향으로 나를 가리킬 수 있습니까? 아니면 내가 필요한 것을 성취하기 위해 JOIN을 사용하고 있습니까?

감사합니다 :)

+0

LINQ에서 생성 된 코드를 확인해야합니다. –

답변

4

이것은 게으른 로딩에 의해 발생 지금까지 나는이에 대해 알고하지 않았다 BrokenGlass의 제안은있다 - 당신이 012을 적용하여 것을 주변에 얻을 수 있습니다(SQL에 EF의 Include() Linq에 대한에 해당) 한 다음 나중에 쿼리를 수행 :

var dlo = new DataLoadOptions(); 
dlo.LoadWith<PersonView>(p => p.OtherViews); 
dc.LoadOptions = dlo; 
//your query here 
1

당신이 당신의 OtherViews 테이블에 쿼리를하고있어 p.OtherViews.Name을 수행 할 때 그것은 게으른 로딩 오류에 LINQ-2-SQL,의 (일명 이연로드) 기능입니다. 그것을 다루는 몇 가지 방법이있다

, 하나는 턴 오프로 연기로드 중입니다 :

또 다른 당신이 당신의 결과에 원하는 모든 것을 투영을 확인하고 프로젝션을 사용하는 것입니다
dc.DeferredLoadingEnabled = false; 

:

var people = from p in dc.PersonViews 
      select new { 
       Person = p, 
       Name = p.OtherViews.Name 
      }; 

그리고 :-)

1

당신이보고있는 이유는 Linq에 그 관계를 지연로드를 사용합니다. 즉, 실제로 사용하려고 시도 할 때까지 Linq는 연결을로드하지 않습니다.

항상 연결이 필요하지 않은 경우 불필요한 JOIN을 수행하지 않아도되고 필요없는 데이터를 검색하지 않기 때문에 성능 향상에 도움이 될 수 있습니다.

데이터가 필요하고 요청을 계속 내 보내면 성능이 저하 될 수 있습니다.

연결을 그대로 유지하면서 DataLoadOptions를 사용할 수 있습니다. 예를 들어,

var dc = new DataContext(); 
dc.DeferredLoadingEnabled = false; 

DataLoadOptions loadOptions = new DataLoadOptions(); 
loadOptions.LoadWith<PersonView>(o => o.OtherView); 

dc.LoadOptions = loadoptions; 

이제 PersonView를 쿼리하면 Anyview는 자동으로 OtherView 관계를로드합니다.

이 접근법에 대한 좋은 점은 필요시 언제든지 켜고 끌 수 있다는 것입니다.

관련 문제