我有两个查询,我正在使用第二个中的第一个结果,如此
var temp = (ObjectTable.Where(o => o.Category == "Y"));
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == temp.Max(x => x.Value))});
有没有办法将这些组合成一个查询?
编辑: 我不能直接链接它们,因为我在第二个查询中使用temp.Max()。
答案 0 :(得分:5)
为什么呢?将它变为三个会更清晰(也更有效率):
var temp = (ObjectTable.Where(o => o.Category == "Y"));
int max = temp.Max(x => x.Value);
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == max)});
答案 1 :(得分:1)
可能最直接的重构是用temp的值替换所有“temp”实例。由于看起来这个值是不可变的,因此重构应该是有效的(但是很难看):
var anonymousObjList = ObjectTable.Where(o => o.Category == "Y")
.Select(o => new {o, IsMax = (o.Value == ObjectTable.Where(o => o.Category == "Y").Max(x => x.Value))});
正如已经指出的那样,这个查询确实没有优势,因为查询使用了deffered执行并且可以构建。我实际上建议更多地分割查询:
var temp = (ObjectTable.Where(o => o.Category == "Y"));
var maxValue = temp.Max(x => x.Value);
var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == maxValue)});
此 比原始更好,因为每次调用“Max”都会导致对整个数据集进行另一次迭代。由于它是在原始选择中调用的,因此被调用了n次。这使得原始的O(n ^ 2)!
答案 2 :(得分:1)
您可以使用let
关键字使用查询语法在一个语句中执行此操作。它只评估'max'一次,所以它就像三个单独的语句一样,只在一行中。
var anonymousObjList = from o in ObjectTable
where o.Category == "Y"
let max = ObjectTable.Max(m => m.Value)
select new { o, IsMax = (o.Value == max) };
这是我唯一一次使用查询语法。你不能使用方法语法来做到这一点!
编辑:ReSharper建议
var anonymousObjList = ObjectTable.Where(o => o.Category == "Y")
.Select(o => new {o, max = ObjectTable.Max(m => m.Value)})
.Select(@t => new {@t.o, IsMax = (@t.o.Value == @t.max)});
然而,这不是最佳的。第一个Select为ObjectTable中的每个项目投射max
属性 - 将为每个项目评估Max函数。如果使用查询语法,则只评估一次。
同样,您只能使用查询语法执行此操作。我不是查询语法的粉丝,但这使它值得,而且是我使用它的唯一情况。 ReSharper错了。