C# Linq索引选择(取二)
好的,我知道C# Linq索引选择(取二),c#,linq,C#,Linq,好的,我知道Select((x,I)=>…)没有文字形式,但我有一个相当复杂的查询,现在有一个新的要求,即一半的预测输出字段依赖于输出“行数”。有没有办法,甚至是一个丑陋的方法来引入索引并以文本形式保留一个查询 另外请注意,并不是所有源行都参与到结果中,所以我不能只将源投影到可枚举索引元组中,索引必须在最终投影之前和所有连接之后应用 编辑: 原始查询很大,因此将其放在这里是没有意义的,让SSI用伪 from a in source where somecondition(a) join b in
Select((x,I)=>…)
没有文字形式,但我有一个相当复杂的查询,现在有一个新的要求,即一半的预测输出字段依赖于输出“行数”。有没有办法,甚至是一个丑陋的方法来引入索引并以文本形式保留一个查询
另外请注意,并不是所有源行都参与到结果中,所以我不能只将源投影到可枚举索引元组中,索引必须在最终投影之前和所有连接之后应用
编辑:
原始查询很大,因此将其放在这里是没有意义的,让SSI用伪
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的索引,并且我需要它,而不需要将查询拆分为两个查询如果您希望“在一个查询中”查询,并且大多数查询是“文本形式”,则必须执行以下操作:
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,其中可能有一些语法错误,但您已经了解了基本情况。)
灵感的眩目闪光
你提到的让魔法让我想到了这一点。在我写的一个快速的例子中,它似乎起了作用
// 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
两次,索引将保持递增。(也就是说,它不会重置为零。)如果您想“在一个查询中”完成此操作,而大多数查询是“文本形式”,则必须执行以下操作:
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,其中可能有一些语法错误,但您已经了解了基本情况。)
灵感的眩目闪光
你提到的让魔法让我想到了这一点。在我写的一个快速的例子中,它似乎起了作用
// 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
两次,索引将保持递增。(即,它不会重置为零。)您的问题不清楚。请添加一些示例代码。您的问题不清楚。请添加一些示例代码。是的,第三个是我目前正在考虑的解决方案,但我不喜欢:)我希望有一些我想不出来的join
或let
magic:)。第一种解决方案只是第三种解决方案的浓缩变体,由于查询的复杂性,我非常希望避免#2。我可以重构它,但那将是对我身后的人的一种仇恨行为:)@mmix这似乎可行,试试看。如果它真的有效,那么坐下来试着找出原因……是的,效果很好,我可以接受这个:)我想我看不见森林,看不见树木:)@mmix好的。请注意(在我最近的编辑中)它有点脆弱,因此请确保它的注释良好,并且您要小心。是的,我认识到危险,必须使用局部var,并让让成为投影前的最后一条语句。谢谢。是的,第三个是我目前正在考虑的解决方案,但我讨厌:)我希望有一些我想不出来的加入或让变魔术:)。第一种解决方案只是第三种解决方案的浓缩变体,由于查询的复杂性,我非常希望避免#2。我可以重构它,但那将是对我身后的人的一种仇恨行为:)@mmix这似乎可行,试试看。如果它真的有效,那么坐下来试着找出原因……是的,效果很好,我可以接受这个:)我想我看不见森林,看不见树木:)@mmix好的。请注意(在我最近的编辑中)它有点脆弱,因此请确保它的注释良好,并且您要小心。是的,我认识到危险,必须使用局部var,并让让成为投影前的最后一条语句。谢谢