我有一个包含客户订单的数据库。 我想使用Linq(到EF)来查询数据库,以便为每个客户带回最后(最近的)3,4 ... n个订单。
注意: 客户1可能在最后一小时内刚刚订购了12个订单;但自上周以来,客户2可能没有提供任何产品。
我不能为我的生活找出如何在linq(lambda表达式)中编写查询以获取数据集。
有什么好主意吗?
修改 客户和订单是一种简化。我查询的表实际上是各种Web服务的出站消息记录。将客户和订单描述为更加容易。关系是一样的。 我正在构建一个任务,检查每个Web服务的最后n条消息,看看是否有任何故障。我们想要一个Web服务的半实时健康状态。
@CoreySunwold
我的表看起来有点像这样:
MessageID,WebserviceID,SentTime,状态,消息,错误,
或者来自客户/订单上下文,如果它更容易:
OrderID,CustomerID,StatusChangedDate,状态,WidgetName,评论
编辑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();
执行需要一段时间。所以我不确定这是否是最有效的表达方式。
答案 0 :(得分:2)
您可以将SelectMany用于此目的:
customers.SelectMany(x=>x.orders.OrderByDescending(y=>y.Date).Take(n)).ToList();
答案 1 :(得分:2)
这应该给出每个客户的最后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()
}
但是,我怀疑这会强制数据库返回整个 Orders表,然后为每个客户挑选最后3个。检查生成的SQL。
如果需要优化,则必须手动构建一个SQL,只返回最后一个,然后将其转换为视图。
答案 2 :(得分:0)
这个怎么样?我知道它适用于常规收藏但不了解EF。
yourCollection.OrderByDescending(item=>item.Date).Take(n);
答案 3 :(得分:0)
var orders = orders.Where(x => x.CustomerID == 1).OrderByDescending(x=>x.Date).Take(4);
这将需要最后4个订单。具体查询取决于您的表/实体结构。
顺便说一下:您可以将x作为订单。所以你可以这样读取:获取订单,其中order.CustomerID等于1,OrderThem by order.Date并取前4行'。
答案 4 :(得分:0)
var ordersByCustomer =
db.Customers.Select(c=>c.Orders.OrderByDescending(o=>o.OrderID).Take(n));
这将返回按客户分组的订单。
答案 5 :(得分:-1)
有人可能会在这里纠正我,但我认为这样做是linq,单个查询可能非常困难,如果不是不可能的话。我会使用商店程序和类似的东西
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"
我暂时没有使用这种语法,所以它可能不太正确,但如果我理解了这个问题,那么我认为这是最好的方法。