使用 OrderBy 优化 Lambda Linq to SQL 查询
我有以下 lambda 表达式:
IEnumerable<Order> query
= _ordersRepository.GetAllByFilter(
o =>
o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
.Status.StatusType.DisplayName != "Completed"
||
o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
.Status.Date > sinceDate
).OrderBy(o => o.DueDate);
如您所见,我必须在主查询中对集合进行两次排序(总共三次)才能执行 OR 查询。
1)查询优化器是否足够聪明,能够有效地处理这个问题?
2)如果不是,我怎样才能重写这个表达式只排序一次,但保持lambda语法?
这链接到上一个问题,它解释了查询如果上面的代码不清楚,请更详细地说明。
I have the following lambda expression:
IEnumerable<Order> query
= _ordersRepository.GetAllByFilter(
o =>
o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
.Status.StatusType.DisplayName != "Completed"
||
o.OrderStatus.OrderByDescending(os => os.Status.Date).First()
.Status.Date > sinceDate
).OrderBy(o => o.DueDate);
As you can see, I'm having to order the collection twice within the main query (so three times in total) in order to perform my OR query.
1) Is the query optimiser clever enough to deal with this in an efficient way?
2) If not, how can I rewrite this expression to only order by once, but keeping with lambda syntax?
This is linked to this previous question, which explains the query in a bit more detail if the above code isn't clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以获取此查询的 SQL(一种方法是使用 SQL 探查器),然后向 SQL Studio 询问执行计划。除非你这样做,否则无法知道优化器的想法。我的猜测是答案是“不”。
像这样:
You can get the SQL for this query (one way is to use the SQL profiler), and then ask SQL Studio for the execution plan. Unless you do this, there is no way to know what the optimizer thinks. My guess is the answer is "no".
Like this:
关于第一点:您可以看到通过订阅 DatabaseContext 对象的输出生成的 SQL。这通常位于名为 Log 的属性中。
至于优化您的查询,请尝试以下操作(我没有测试过,所以我不知道它是否会起作用)
希望这只会执行一次子查询,并且还执行 max 而不是 top 1 的 order by 。
Regarding your first point: You can see the SQL that is generated by subscribing to the output of the DatabaseContext object. This is usually in a property called Log.
As for optimising your query, try the following (I've not tested it so I don't know if it will work)
Hopefully that will only perform the subquery once, and also performs a max rather than an order by with top 1.