Linq索引选择(拿两个)

时间:2012-06-01 08:56:20

标签: c# linq

好的,我知道Select((x, i) => ...)没有文字形式,但我有一个相当复杂的查询,现在有一个新的要求,使一半的预计输出字段依赖于输出“行号”。有没有办法,甚至是一个丑陋的方法来引入索引并保留一个文字形式的查询?

另请注意,并非所有源行都参与结果,因此我不能将源项目投影到可枚举的索引元组中,必须在最终投影之前以及所有连接之后应用索引。

编辑:

原始查询很大,所以将它放在这里毫无意义,让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的索引,我需要它而不需要在两个查询中拆分查询

1 个答案:

答案 0 :(得分: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两次,则索引会继续递增。 (即它不会重置为零。)