组合两个简单的相关 linq 查询

发布于 2024-10-19 06:50:26 字数 298 浏览 1 评论 0原文

我有两个查询,并且我在第二个查询中使用第一个查询的结果,

 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() 。

I have two queries and i'm using the result of the first one in the second one like this

 var temp  = (ObjectTable.Where(o => o.Category == "Y"));
 var anonymousObjList = temp.Select(o => new {o, IsMax = (o.Value == temp.Max(x => x.Value))});

Is there a way to combine these into one query?

EDIT:
I cannot just chain them directly because I'm using temp.Max() in the second query.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧梦荧光笔 2024-10-26 06:50:26

为什么?将其改为三个会更清晰(也更有效):

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)});

Why? it would be clearer (and more efficient) to make it three:

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)});
葬花如无物 2024-10-26 06:50:26

可以使用查询语法并使用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 是错误的。

You can do it in one statement using query syntax, using the let keyword. It only evaluates the 'max' once, so it just like the three separate statements, just in one line.

var anonymousObjList = from o in ObjectTable
                       where o.Category == "Y"
                       let max = ObjectTable.Max(m => m.Value)
                       select new { o, IsMax = (o.Value == max) };

This is the only time I ever use query syntax. You can't do this using method syntax!

edit: ReSharper suggests

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)});

however this is not optimal. The first Select is projecting a max Property for each item in ObjectTable - the Max function will be evaluated for every item. If you use query syntax it's only evaluated once.

Again, you can only do this with query syntax. I'm not fan of query syntax but this makes it worthwhile, and is the only case in which I use it. ReSharper is wrong.

≈。彩虹 2024-10-26 06:50:26

最直接的重构可能是将所有“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))});

正如已经指出的那样,该查询实际上比原始查询没有任何优势,因为查询使用延迟执行并且可以构建。我实际上建议进一步拆分查询

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”都会导致整个数据集的另一次迭代。由于它是在原始的 Select 中调用的,因此 Max 被调用了 n 次。这使得原来的 O(n^2)!

Possibly the most straightfirward refactoring is to replace all instances of "temp" with the value of temp. Since it appears that this value is immutable, the refactoring should be valid (yet ugly):

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))});

As has already been pointed out, this query really has no advantages over the original, since queries use deffered execution and can be built up. I would actually suggest splitting the query even more:

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)});

This is better than the original because every time "Max" is called causes another iteration over the entire dataset. Since it is being called in the Select of the original, Max was being called n times. That makes the original O(n^2)!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文