asp.net 如何根据一定的标准对元素列表进行“分组”,但同时将其保持为列表?.NET Core 7

h7wcgrx3  于 2023-04-13  发布在  .NET
关注(0)|答案(1)|浏览(155)

我们正在开发一个Web应用程序的后端。用户可以通过一个路由查看他们以前的所有订单,该路由将它们作为一个列表从数据库中返回。每个订单都包含诸如金额,状态(待定/成功/失败),项目类型等信息。用户可以通过列表进行筛选/排序。
现在,我的团队的任务是让用户能够根据一定的标准对他们的订单列表进行分组,比如状态。用户还将显示每个“组”的总金额。例如,列表将被排序,以便“成功”的交易排在第一位,然后是待定的交易,然后是失败的交易。
现在,我们在OrderService中的代码返回一个订单列表。谁能给予一个想法,我们如何对列表进行分组,但保留List作为数据类型,因为这是OrderService中的GetOrders方法所做的事情?
我尝试的是:
我们都考虑过使用GroupBy方法found here,但我不认为它会返回一个列表。
任何帮助感激不尽。

jaql4c8m

jaql4c8m1#

如果您的输出必须是对象的列表(或序列)而不是分组项目的列表(列表的列表),那么您可以得到的最接近的是按分组标准对列表进行排序。对最终用户来说,重要的是如何在应用程序中显示该列表......并且您可以在应用程序层中执行您想要的任何分组和/或排序。
GroupBy是一个很难处理的问题,因为它在SQL上产生的结果与在内存中产生的结果不同。实际的排序很大程度上取决于您使用的ORM生成的SQL,我还没有找到一个ORM,它从SQL查询中产生的顺序与我从内存中的等效语句中获得的顺序相同。因此,您可能应该避免尝试使用GroupBy进行排序,并在需要排序时使用SortBy扩展。
分组显示是常见的做法,这完全是应用程序层的问题。如果应用程序保证ASP.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))

这个故事的寓意是:不要使用GroupBy,只需一个简单的OrderBy即可。
更一般地说,GroupBy应该限制在两个主要用例中:
1.分区聚合(汇总记录组)。
1.向数据添加组级信息。
无论哪种情况,都涉及到与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个价值订单)或任何您希望显示的内容,而不是将其构建到复杂的业务逻辑中。

相关问题