2012-06-01 21 views
0

好吧,我知道Select((x, i) => ...)沒有字面形式,但我有一個相當複雜的查詢,現在有一個新的要求,使得一半的投影輸出字段依賴於輸出「行號」 。有什麼辦法,即使是一個醜陋的引入索引並保留一個字面形式的查詢嗎?Linq索引選擇(帶兩個)

另請注意,並非所有源行都參與結果,因此我不能將源項目投影到可枚舉的索引元組中,索引必須在最終投影之前以及所有連接和派發之後應用。

編輯:

原始查詢大所以它毫無意義,把它放在這裏,讓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的,有可能是在那裏一些語法錯誤,但你得到的總體思路。)

盲目化靈感FLASH

你的let提魔術讓我受益匪淺。它似乎在我寫下的一個快速示例中起作用。

// 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

是的,第三個是我目前正在考慮的解決方案,但會討厭它:)我希望有一些'join'或'let' magic :),我想不出來。第一種解決方案僅僅是第三種解決方案的簡明變體,而我非常希望避免#2因爲查詢的複雜性。我可以重構它,但這將是一個仇恨的行爲,以追求我的人:) – mmix

+0

@mmix看這個空間,我想我有東西... – Rawling

+0

@ mmix這_seems_工作,試試看。如果它確實起作用,那就坐下來試着弄清楚爲什麼... – Rawling