实体框架 - 使用 Linq 为每个客户恢复最后 3,4..n 个订单



我有一个包含客户订单的数据库。我想使用 Linq(到 EF)查询数据库,为每个客户带回最后(最新的)3,4...n 个订单。

注意:客户 1 可能在过去一小时内刚刚下了 12 个订单;但客户 2 可能自上周以来就没有做过任何工作。

我一生都无法弄清楚如何在 linq(lambda 表达式)中编写查询以取回数据集。

有什么好主意吗?

编辑:客户和订单是一种简化。我正在查询的表实际上是发送到各种 Web 服务的出站消息的记录。描述为客户和订单似乎更容易。关系是一样的。我正在构建一个任务,用于检查每个 Web 服务的最后 n 条消息,以查看是否有任何失败。我们想要网络服务的半实时运行状况。


@CoreySunwold我的表格看起来有点像这样:
消息 ID, 网络服务ID, 发送时间, 状态, 消息, 错误,

或者从客户/订单上下文中,如果它使它更容易:
订单 ID、客户 ID、状态更改日期、状态、小部件名称、注释

编辑 2:我最终想出了一些办法
(帽子提示给@StephenChung谁基本上想出了完全相同的,但在经典的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();

执行确实需要一段时间。所以我不确定这是否是最有效的表达方式。

这应该给出每个客户的最后 3 个订单(如果有订单):

from o in db.Orders
group o by o.CustomerID into g
select new {
  CustomerID=g.Key,
  LastOrders=g.OrderByDescending(o => o.TimeEntered).Take(3).ToList()
}

但是,我怀疑这会强制数据库在为每个客户挑选最后 3 个之前返回整个 Orders 表。 检查生成的 SQL。

如果需要优化,则必须手动构造一个 SQL,使其最多只返回最后 3 个,然后将其放入视图中。

您可以使用 SelectMany 来实现此目的:

customers.SelectMany(x=>x.orders.OrderByDescending(y=>y.Date).Take(n)).ToList();

这个怎么样?我知道它可以与常规集合一起使用,但不了解 EF。

yourCollection.OrderByDescending(item=>item.Date).Take(n);
var ordersByCustomer = 
db.Customers.Select(c=>c.Orders.OrderByDescending(o=>o.OrderID).Take(n));

这将返回按客户分组的订单。

var orders = orders.Where(x => x.CustomerID == 1).OrderByDescending(x=>x.Date).Take(4);

这将需要最后 4 个订单。具体查询取决于您的表/实体结构。

顺便说一句:你可以把x作为订单。所以你可以这样读:在订单的地方获取订单。客户 ID 等于 1,按订单订购。日期并取前 4 行。

有人可能会在这里纠正我,但我认为使用单个查询来做到这一点可能是非常困难的,如果不是不可能的话。我会使用商店程序和类似的东西

select 
    *
    ,RANK() OVER  (PARTITION BY c.id ORDER BY o.order_time DESC) AS 'RANK'
from 
    customers c 
inner join 
    order o
on 
    o.cust_id = c.id
where 
    RANK < 10 -- this is "n"

我已经有一段时间没有使用这种语法了,所以它可能不太正确,但如果我理解这个问题,那么我认为这是最好的方法。

相关内容

  • 没有找到相关文章

最新更新