2012-06-01 2 views
0

Хорошо, я знаю, что Select((x, i) => ...) не имеет литеральной формы, но у меня довольно сложный запрос, который теперь имеет новое требование, в результате чего половина проецируемых полей вывода зависит от вывода «номер строки», , Есть ли способ, даже уродливый, ввести индекс и сохранить один запрос в литеральной форме?Linq индексированный выбор (возьмите два)

Также обратите внимание, что не все исходные строки участвуют в результате, поэтому я не могу просто проецировать исходный код на перечислимые индексированные кортежи, индексы должны применяться перед окончательной проекцией и после всех объединений и wheres.

Edit:

Исходный запрос велик поэтому его бессмысленно ставить его здесь, пусть 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 волшебство сделало меня этим. Кажется, это работает в кратком примере, который я написал.

// 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, индекс продолжает увеличиваться. (I.e. не сбрасывается на ноль.)

+0

Да, третий вариант - это решение, которое я сейчас рассматриваю, но ненавижу его :) Я надеюсь на какую-то 'join' или' let' magic :), о которой я не могу думать. Первое решение - это просто сокращенная вариация третьего, и я серьезно стараюсь избегать # 2 из-за сложности запроса. Я мог бы реорганизовать его, но это было бы актом ненависти к человеку, идущему за мной :) – mmix

+0

@mmix Посмотрите это пространство, я думаю, что у меня есть что-то ... – Rawling

+0

@mmix Это _seems_ для работы, попробуйте. Если это сработает, тогда сядьте и попытайтесь понять, почему ... – Rawling

Смежные вопросы