2012-06-01 3 views
0

좋아, 나는 그 글자 양식이없는 것을 알고 있지만 지금은 투영 된 출력 필드의 절반을 출력 "행 번호"에 종속되게 만드는 새로운 요구 사항이있는 상당히 복잡한 쿼리를 가지고 있습니다. . 인덱스를 소개하고 하나의 쿼리를 리터럴 형식으로 유지하는 방법은 없습니까?Linq 인덱스 선택

또한 모든 원본 행이 결과에 참여하지 않기 때문에 열거 형 인덱스 튜플에 프로젝트 소스를 넣을 수 없으며 최종 프로젝션 전에 인덱스를 적용하고 모든 조인과 wheres를 적용해야합니다.

편집 :

원래 쿼리는 큰 그래서 그 여기에 넣어 의사와 ssimplify 수 있도록하는 것이 무의미

from a in source 
where somecondition(a) 
join b in source2 on a.key equals b.key 
where someothercondition(a, b) 
select new 
{ 
    f1 = a.f1, 
    oldf2 = func(a.field, b.field), 
    newf2 = func(a.field, b.field, index) 
    // ... (20 somthing more projected fields) 
} 

내가 newf2에 대한 인덱스를 필요로하고 내가 두 쿼리에 쿼리를 분할하지 않고 필요 당신이 "문자 형태"의 대부분이 "하나 개의 쿼리를"원하는 경우

+2

질문이 명확하지 않습니다. 샘플 코드를 추가하십시오. – jeroenh

+0

LINQ to SQL입니까? –

+0

아니, 그 일반 linq – mmix

답변

3

, 당신은해야 할 것 같은 뭔가 :

from t in 
    (
     (
      from a in source 
      where somecondition(a) 
      join b in source2 
      on a.key equals b.key 
      where someothercondition(a, b) 
      select new { a = a, b = b } 
     ).Select((x, i) => new { index = i, a = x.a, b = x.b }) 
    ) 
select new { 
    f1 = t.a.f1, 
    oldf2 = func(t.a.field, t.b.field), 
    newf2 = func(t.a.field, t.b.field, t.index) 
    // ... (20 somthing more projected fields) } 

하지만 이것은 끔찍한입니다.

a 
    .Where(a => somecondition(a)) 
    .Join(b, a => a.key, b => b.key, (a,b) => new { a = a, b = b }) 
    .Where(pair => somecondition(pair.a, pair.b)) 
    .Select((t, i) => new 
     { 
      f1 = t.a.f1, 
      oldf2 = func(t.a.field, t.b.field), 
      newf2 = func(t.a.field, t.b.field, i) 
      // ... 
     }); 

조인 구문은 더 추한,하지만 적어도 당신은 구문을 혼합하지 않는 :

나는 . 형태로 모두 넣어 원합니다.

당신은

var pairs = 
    from a in source 
    where somecondition(a) 
    join b in source2 
    on a.key equals b.key 
    where someothercondition(a, b) 
    select new { a = a, b = b }; 

var indexedPairs = pairs.Select((x, i) => new { index = i, a = x.a, b = x.b }); 

var projectedIndexedPairs = 
    from t in indexedPairs 
    select new { 
     f1 = t.a.f1, 
     oldf2 = func(t.a.field, t.b.field), 
     newf2 = func(t.a.field, t.b.field, t.index) 
     // ... (20 somthing more projected fields) 
     }; 

을 선호 수도 있지만 그것은 "하나 개의 질의에"아니다 ...

(이 LINQ의 많은입니다, 거기에 몇 가지 구문 오류가있을 수 있지만, 당신은 일반적인 아이디어를 얻을.)

는 영감의 플래시 눈부신

let의 멘션 마술은 나에게 이것의 thik을 만들었다. 그것은 내가 작성한 빠른 예에서 작동하는 것 같습니다.

// Copious commenting to explain what you're doing. 
int x = 0; 

// Copious commenting to explain what you're doing. 
var query = 
    from a in source 
    where somecondition(a) 
    join b in source2 
    on a.key equals b.key 
    where someothercondition(a, b) 
    let i = x++ 
    select new { 
     f1 = a.f1, 
     oldf2 = func(a.field, b.field), 
     newf2 = func(a.field, b.field, i), 
     // ... (20 somthing more projected fields) 
     }; 

업데이트 : 다소 취약합니다. 예를 들어 query을 두 번 반복하면 인덱스가 계속 증가합니다. (즉, 0으로 재설정되지 않습니다.)

+0

그래, 세 번째는 내가 현재 고려하고있는 해결책이지만, 그것을 싫어한다 :) 나는 생각할 수없는 일부'join' 또는'let' magic을 기대하고있다. 첫 번째 솔루션은 세 번째 솔루션의 응축 된 변형이며 쿼리의 복잡성 때문에 # 2를 피하려고 진지하게 생각하고 있습니다. 나는 그것을 리팩토링 할 수있다. 그러나 그것은 나에게 오는 사람에 대한 증오의 행동이 될 것이다. :) – mmix

+0

@mmix이 공간을 보면서, 나는 내가 뭔가를 가지고 있다고 생각한다 ... – Rawling

+0

@mmix 이것은 노력해야한다. 그것이 작동한다면, 왜 앉아서 노력해야하는지 ... – Rawling