我们正在开发一个web应用程序的后端。用户可以通过一个路由查看他们以前的所有订单,该路由将它们作为一个列表从数据库返回。每个订单都包含诸如数量、状态(待定/成功/失败)、商品类型等信息。用户可以筛选/排序列表。
现在,我的团队的任务是使用户能够根据特定的标准(比如状态)对他们的订单列表进行分组。用户还将看到每个"组"的总金额。例如,列表将被排序为"成功"事务首先出现,然后是挂起的事务,然后是失败的事务。
。OrderService中的代码返回一个订单列表。谁能给一个想法,我们如何可以分组列表,但保留列表作为一个数据类型,因为这是什么GetOrders方法在OrderService ?
What I tried:
我们都考虑过使用这里找到的GroupBy方法,但我认为它根本没有返回列表。
感谢您的帮助。
如果您的输出必须是对象的列表(或序列),而不是分组项目的列表(列表的列表),那么您可以得到的最接近的方法是按分组标准对列表进行排序。对最终用户来说,重要的是如何在应用程序中显示该列表……你可以在应用层执行任何你想要的分组和/或排序。
GroupBy
是一个困难的野兽,因为它在SQL上产生的结果与在内存中产生的结果不同。实际的排序在很大程度上取决于您正在使用的ORM生成的SQL,而且我还没有找到一个ORM能够从SQL查询中产生与从内存中的等效语句中得到的相同的排序。因此,您可能应该避免尝试使用GroupBy
进行排序,而在需要排序时使用SortBy
扩展。
分组显示是常见的做法,这完全是应用层的问题。如果您的应用程序保证ASP. js的源数据中的特定顺序。NET页面上,您可以通过跟踪每条记录上的组键并在键更改时插入标题行来潜在地生成组标题,这保留了数据层提供的数据顺序。这在页列表中是理想的,其中控制器根据定义良好的顺序处理行选择。
例如,让我们使用一个简化的视图模型:public record OrderViewModel
(
Guid OrderID,
Guid VendorID,
string VendorName,
string ItemName,
Decimal ItemCost,
int Quantity,
Decimal Total
);
让我们假设我们要呈现的数据已经按VendorName
和其他一些(非常重要但未在视图模型中交付)字段排序。您可以将其呈现为HTML表,并以各种方式进行分组,包括:
@(
var lastVendorID = Guid.Empty;
)
<table>
@foreach (var order in Model)
{
if (order.VendorID != lastVendorID)
{
lastVendorID = order.VendorID;
<tr class="vendor-row"><td colspan=4>@order.VendorName</td></tr>
}
<tr class="item-row">
<td>@order.ItemName</td>
<td>@($"${order.ItemCost:#,0.00}")</td>
<td>@order.Quantity</td>
<td>@($"${order.Total:#,0.00}")</td>
</tr>
}
</table>
如果我们不假设源已经排序,那么你可以在foreach
:
@foreach (var order in Model.OrderBy(o => o.VendorName))
这个故事的寓意是:当你需要一个简单的OrderBy
时,不要GroupBy
。
更一般地说,GroupBy
应该被限制在两个主要的用例中:
- 分区聚合(汇总记录组)。
- 向数据中添加组级信息。
两种情况都涉及到与Order
项目的普通列表明显不同的输出记录。要么生成汇总数据列表,要么添加与整个组相关的信息。例如:
public record OrderGroupViewModel
(
// Group key and display data
Guid GroupID,
string GroupName,
// summarized from order data:
int OrderCount,
Decimal TotalOrderValue,
// Line item collection - could be List<> or whatever you prefer
Order[] Orders
)
表生成代码然后嵌套两个循环:一个用于OrderGroupViewModel
的外部循环和一个用于Orders
集合的内部循环。您可以在订单列表中执行摘要、排序和选择(例如显示前10个值订单)或其他任何您希望显示的内容,而不是将其构建到复杂的业务逻辑中。