2010-06-22 4 views
1

Linq-To-SQL을 사용하여 비즈니스 계층을 채우고 있습니다. 이 코드를 실행하면단일 SQL 명령 만 실행하도록이 LINQ 쿼리를 최적화하려면 어떻게해야합니까?

fund.FundEntities = fundGroup.tFunds 
    .Select(fe => 
    { 
     var fundEntity = new FundEntity() 
     { 
      BankAccount = null, 
      CloseDate = fe.closeDate ?? new DateTime(), 
      Commitment = fe.commitment ?? 0, 
      CommitmentEndDate = fe.closeDate ?? new DateTime(), 
      Fund = fund 
     }; 
     fundEntity.CapitalCalls = fe.tCapitalCalls 
      .Select(cc => 
      { 
       return new CapitalCall() 
       { 
        Amount = cc.agrAmount ?? 0, 
        FundEntity = fundEntity 
       }; 
      } 
      ); 
     return fundEntity; 
    }); 

, 그것은 런타임에 개별 CapitalCalls에 대한 쿼리를 실행합니다 : 여기에 내가 일하고 쿼리의 조각이다. 어쨌든 동일한 비즈니스 객체 구조 (IE - 비즈니스 오브젝트 내에서 Fund -> FundEntity -> CapitalCall과의 관계)를 유지하기 위해 이것을 다시 설계 할 수 있습니까?하지만 한 번에 전체 테이블을로드합니까? 이상적으로는 완전히 조인 된 기금이 될 많은 조인이있는 단일 SQL 쿼리가있을 것입니다.

+0

ToList()를 호출하는 이유는 무엇입니까? –

+0

FundEntity의 CapitalCall 속성이 List 유형이기 때문에 Shawn

+0

Hrmm 나는 그들을 IEnumberable로 만들 수 있다고 생각하지만 런타임에 1을 1 회씩 쿼리합니다 ... – Shawn

답변

1
var fund = GetFund(); 
var fundGroup = GetFundGroup(); 
var dataContest = GetDataContext(); 


List<int> feIds = fundGroup.tFunds.Select(fe => fe.FundEntityId).ToList(); 

//before: iterate through local collection fundGroup.tFunds 
// and issue one CapitalCall query per fundEntity. 
//after: send all the fundEntityIds into the database in one query 
// that also fetches related CapitalCalls. 
var query = 
    from fe in dataContext.tFunds 
    where feIds.Contains(fe.FundEntityId)) 
    let capitalCalls = fe.tCapitalCalls 
    select new {FundEntity = fe, CapitalCalls = capitalCalls.ToList() }; 

foreach(var record in query) 
{ 
    FundEntity fundEntity = new FundEntity() 
    { 
    CloseDate = record.fe.closeDate ?? new DateTime(), 
    ... 
    } 
    fundEntity.CapitalCalls = ... 
} 
3

문제를 해결하려면 동시에 여러 쿼리를 실행하고 결과 데이터를 함께 바인딩해야합니다. LINQ to SQL이이를 수행 할 수는 있지만 기본적으로 그러한 기능을 지원하지는 않습니다.

PLINQO는 LINQ to SQL 대신 프레임 워크에 기능을 추가하는 오픈 소스를 대체하고 개선 한 오픈 소스입니다. 특히 배치 쿼리와 미래 쿼리에 관심이 있습니다.

하는 데 도움이 http://www.plinqo.com

희망에 그것을 확인! 대신 앞으로의 뒤로가는 것 같은 톰 듀폰 (PLINQO 개발의 회원 팀)

+0

문제의 실제 해결책은 올바른 데이터를 제공하는 단일 쿼리를 작성한 다음 결과를 로컬로 형성하는 것입니다. –

0

나에게 보인다. Fund -> FundEntity -> CapitalCalls로 이동하려고하지만 각각에 컨테이너에 대한 참조를 주려고합니다.

ToList을 호출 한 다음 해당 개체를 Linq를 사용하여 원하는 구조로 다시 투영하는 데이터베이스에 대해 간단한 쿼리를 수행하는 것이 좋습니다.

쿼리를 다른 방법으로 작성하고 그룹화 기준을 사용하는 것도 고려해 볼 수 있습니다. 개념적으로는 자본금을 받고 기금 실체별로 그룹화 한 다음 기금별로 그룹화합니다.

컨테이너 참조 없이도 사용할 수 있다고 생각되는 경우 다음과 같이 쿼리를 표현할 수 있습니다.이 쿼리는 하나의 쿼리에서 조인을 사용해야합니다.

fund.FundEntities = fundGroup.tFunds 
.Select(fe => 
{ 
    new FundEntity 
    { 
     BankAccount = null, 
     CloseDate = fe.closeDate ?? new DateTime(), 
     Commitment = fe.commitment ?? 0, 
     CommitmentEndDate = fe.closeDate ?? new DateTime(), 
     CapitalCalls = fe.tCapitalCalls 
     .Select(cc => 
     { 
      new CapitalCall 
      { 
       Amount = cc.agrAmount ?? 0 
      }; 
     } 
    } 
}); 
+0

개체 모델 정렬이 원으로 이루어지기 때문에 나는 기울지 않고 때로는 트리를 가로 질러 갈 필요가 있습니다. 어쨌든 나는 단지 데이터 집합을 사용하고있다. – Shawn

0
내가 SteadyEddi (나는 FundEntity 포함이) 같은 것을 함께 갈 것입니다,하지만 난 당신이로 원하는 (또는 SteadyEddi과 동등한 비 LINQ 방법) 정확히처럼 표현할 수 있다고 생각

:

fund.FundEntities = 
from fe in fundGroup.tFunds 
select new FundEntity() 
{ 
    BackAccount = null, 
    CloseDate = fe.closeDate ?? new DateTime(), 
    Commitment = fe.commitment ?? 0, 
    CommitmentEndDate = fe.closeDate ?? new DateTime(), 
    Fund = fund, 
    CapitalCalls = from cc in fe.tCapitalCalls 
        select new CapitalCall() 
        { 
         Amount = cc.agrAmount ?? 0, 
         FundEntity = fundEntity 
        } 
} 

그렇지 않다면, 나는 정말로 어쨌든 다시 고려되어야하는 귀하의 데이터베이스 매핑에서 뭔가가 일어나고 있다고 생각합니다. 나쁜 이름 등. CloseDate == CommitmentEndDate. 귀하의 코드에 문제가있을 수 있습니다 당신이 CapitalCalls 자신을 건설하고 그래서 LINQ - TO - SQL은 표현 트리를 제대로 디코딩 할 수 없습니다. 그러나 다시, 나는 내 코드를 테스트하지 않았으므로 내 코드가 작동하는지 여부는 알 수 없다.

+0

참으로 그 질문의 일부가 아니었다. 그 속성은 이전 버전과의 호환성을위한 것입니다. 쓸데없는/주석 처리 된 것으로 표기됩니다 – Shawn

+0

충분히 공정 :) 내 코드가 당신의 예제에서 작동 했습니까? 나중에 LINQ-TO-SQL은 단일 표현식 lambdas 만 처리 할 수 ​​있습니다. "LINQ-TO-SQL은 표현식 트리를 올바르게 디코딩하지 못할 수도 있습니다." 안부 인사, Lasse Logged –

관련 문제