好的,我知道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的索引,我需要它而不需要在两个查询中拆分查询
答案 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
两次,则索引会继续递增。 (即它不会重置为零。)