使用 Linq 为每个客户带回最后 3,4...n 个订单
我有一个包含客户订单的数据库。 我想使用 Linq(到 EF)查询数据库以返回每个客户的最后(最近)3,4...n 订单。
笔记: 客户 1 在过去一小时内可能刚刚下了 12 个订单;但客户 2 可能自上周以来就没有做过任何事情。
我一生都无法弄清楚如何在 linq (lambda 表达式)中编写查询来获取数据集。
有什么好主意吗?
编辑: 客户和订单是一种简化。我正在查询的表实际上是各种 Web 服务的出站消息的记录。描述为客户和订单似乎更容易。关系是一样的。 我正在构建一个任务来检查每个 Web 服务的最后 n 条消息,以查看是否存在任何故障。我们想要网络服务的半实时健康状态。
@CoreySunwold
我的桌子看起来有点像这样:
MessageID、WebserviceID、SentTime、状态、消息、错误
或者来自客户/订单上下文(如果这样更容易):
OrderID、CustomerID、StatusChangedDate、Status、WidgetName、Comments
编辑 2: 我最终解决了一些问题
(向@StephenChung致敬,他基本上想出了完全相同的方法,但是是在经典的linq中)
var q = myTable.Where(d => d.EndTime > DateTime.Now.AddDays(-1))< br> .GroupBy(g => g.ConfigID)
.Select(g =>新 { 配置ID = g.Key, 数据 = g.OrderByDescending(d => d.EndTime) .Take(3).Select(s => 新 { s.状态, 发送时间 }) }).ToList();
执行确实需要一段时间。所以我不确定这是否是最有效的表达方式。
I have a database with customers orders.
I want to use Linq (to EF) to query the db to bring back the last(most recent) 3,4...n orders for every customer.
Note:
Customer 1 may have just made 12 orders in the last hr; but customer 2 may not have made any since last week.
I cant for the life of me work out how to write query in linq (lambda expressions) to get the data set back.
Any good ideas?
Edit:
Customers and orders is a simplification. The table I am querying is actually a record of outbound messages to various web services. It just seemed easer to describe as customers and orders. The relationship is the same.
I am building a task that checks the last n messages for each web service to see if there were any failures. We are wanting a semi real time Health status of the webservices.
@CoreySunwold
My table Looks a bit like this:
MessageID, WebserviceID, SentTime, Status, Message, Error,
Or from a customer/order context if it makes it easer:
OrderID, CustomerID, StatusChangedDate, Status, WidgetName, Comments
Edit 2:
I eventually worked out something
(Hat tip to @StephenChung who basically came up with the exact same, but in classic linq)
var q = myTable.Where(d => d.EndTime > DateTime.Now.AddDays(-1))
.GroupBy(g => g.ConfigID)
.Select(g =>new
{
ConfigID = g.Key,
Data = g.OrderByDescending(d => d.EndTime)
.Take(3).Select(s => new
{
s.Status,
s.SentTime
})
}).ToList();
It does take a while to execute. So I am not sure if this is the most efficient expression.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这应该给出每个客户的最后 3 个订单(如果有订单):
但是,我怀疑这将迫使数据库在为每个客户挑选最后 3 个订单之前返回整个 Orders 表。检查生成的SQL。
如果需要优化,则必须手动构造一条 SQL 只返回最后 3 个,然后将其放入视图中。
This should give the last 3 orders of each customer (if having orders at all):
However, I suspect this will force the database to return the entire Orders table before picking out the last 3 for each customer. Check the SQL generated.
If you need to optimize, you'll have to manually construct a SQL to only return up to the last 3, then make it into a view.
您可以使用 SelectMany 来实现此目的:
You can use SelectMany for this purpose:
这个怎么样?我知道它可以与常规集合一起使用,但不知道 EF。
How about this? I know it'll work with regular collections but don't know about EF.
这将返回按客户分组的订单。
This will return the orders grouped by customer.
这将需要最后 4 个订单。具体查询取决于你的表/实体结构。
顺便说一句:您可以将 x 作为订单。因此,您可以这样阅读:获取 order.CustomerID 等于 1 的订单,按 order.Date 获取 OrderThem 并获取前 4 行。
This will take last 4 orders. Specific query depends on your table / entity structure.
Btw: You can take x as a order. So you can read it like: Get orders where order.CustomerID is equal to 1, OrderThem by order.Date and take first 4 'rows'.
有人可能会在这里纠正我,但我认为使用单个查询执行此操作即使不是不可能,也可能非常困难。我会使用存储过程和类似的东西,
我已经有一段时间没有使用这种语法了,所以它可能不太正确,但如果我理解这个问题,那么我认为这是最好的方法。
Somebody might correct me here, but i think doing this is linq with a single query is probably very difficult if not impossible. I would use a store procedure and something like this
I've not used this syntax for a while so it might not be quite right, but if i understand the question then i think this is the best approach.