You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Razor页面实现正确嵌套分组及统计功能?

解决方案:Razor页面嵌套分组与小计/总计实现

核心问题分析

你遇到的ArrestOfficer在每个ArrestDept下重复显示的问题,本质是没有在后端对数据进行正确的关联分组,前端视图直接遍历全量数据,自然会出现所有Officer绑定到每个Dept的情况。视图仅负责数据展示,过滤、分组这类逻辑必须在后端处理,否则不仅逻辑混乱,还会带来性能损耗。

步骤1:后端整理分组数据

在Razor页面的.cs文件(PageModel)中,用LINQ对原始数据进行嵌套分组,确保每个ArrestDept下只包含属于它的ArrestOfficer,同时提前计算各级合计值,避免前端重复计算。

示例代码:

public class ArrestReportModel : PageModel
{
    // 假设原始数据模型是Arrecord,包含ArrestDept、ArrestOfficer、Amount等字段
    public List<DeptGroup> GroupedData { get; set; }
    public decimal TotalGrand { get; set; }

    public void OnGet()
    {
        // 模拟原始数据,实际从数据库/接口获取
        var rawData = new List<Arrecord>
        {
            new Arrecord { ArrestDept = "City A", ArrestOfficer = "Officer1", Amount = 100 },
            new Arrecord { ArrestDept = "City A", ArrestOfficer = "Officer1", Amount = 200 },
            new Arrecord { ArrestDept = "City A", ArrestOfficer = "Officer2", Amount = 150 },
            new Arrecord { ArrestDept = "City B", ArrestOfficer = "Officer3", Amount = 300 },
            new Arrecord { ArrestDept = "City B", ArrestOfficer = "Officer4", Amount = 250 }
        };

        // 嵌套分组:先按Dept分组,再按Officer分组,同时计算每个Officer的小计
        GroupedData = rawData
            .GroupBy(d => d.ArrestDept)
            .Select(deptGroup => new DeptGroup
            {
                DeptName = deptGroup.Key,
                OfficerGroups = deptGroup
                    .GroupBy(o => o.ArrestOfficer)
                    .Select(officerGroup => new OfficerGroup
                    {
                        OfficerName = officerGroup.Key,
                        Entries = officerGroup.ToList(),
                        OfficerTotal = officerGroup.Sum(x => x.Amount)
                    })
                    .ToList(),
                DeptTotal = deptGroup.Sum(x => x.Amount)
            })
            .ToList();

        // 计算报表总计
        TotalGrand = GroupedData.Sum(d => d.DeptTotal);
    }

    // 定义分组模型类
    public class DeptGroup
    {
        public string DeptName { get; set; }
        public List<OfficerGroup> OfficerGroups { get; set; }
        public decimal DeptTotal { get; set; }
    }

    public class OfficerGroup
    {
        public string OfficerName { get; set; }
        public List<Arrecord> Entries { get; set; }
        public decimal OfficerTotal { get; set; }
    }

    // 原始数据模型
    public class Arrecord
    {
        public string ArrestDept { get; set; }
        public string ArrestOfficer { get; set; }
        public decimal Amount { get; set; }
        // 其他字段...
    }
}

步骤2:前端视图展示分组与合计

在.cshtml文件中,遍历后端传递的分组数据,依次展示Dept、Officer、明细,以及各级合计:

示例代码:

<table class="table table-bordered">
    <thead>
        <tr>
            <th>部门</th>
            <th>警员</th>
            <th>金额</th>
            <!-- 其他列... -->
        </tr>
    </thead>
    <tbody>
        @foreach (var dept in Model.GroupedData)
        {
            <!-- 部门行 -->
            <tr>
                <td rowspan="@(dept.OfficerGroups.Sum(o => o.Entries.Count) + dept.OfficerGroups.Count + 1)">
                    @dept.DeptName
                </td>
            </tr>

            @foreach (var officer in dept.OfficerGroups)
            {
                <!-- 警员行 -->
                <tr>
                    <td rowspan="@(officer.Entries.Count + 1)">@officer.OfficerName</td>
                </tr>

                <!-- 明细行 -->
                @foreach (var entry in officer.Entries)
                {
                    <tr>
                        <td>@entry.Amount</td>
                        <!-- 其他列... -->
                    </tr>
                }

                <!-- 警员小计行 -->
                <tr>
                    <td><strong>警员小计: @officer.OfficerTotal</strong></td>
                </tr>
            }

            <!-- 部门总计行 -->
            <tr>
                <td><strong>部门总计: @dept.DeptTotal</strong></td>
            </tr>
        }
    </tbody>
    <tfoot>
        <tr>
            <td colspan="2"><strong>报表总计: @Model.TotalGrand</strong></td>
        </tr>
    </tfoot>
</table>

关键说明

  • 为什么不能仅靠视图实现?视图的职责是展示数据,而非处理业务逻辑。如果在视图中通过循环过滤数据,不仅会写出冗余代码,还会因为遍历全量数据导致性能下降,尤其数据量大时问题更明显。后端提前分组计算,既符合MVC的职责分离原则,也能提升页面渲染效率。
  • 分组逻辑采用LINQ的GroupBy嵌套,确保数据关联正确,从根源解决Officer重复显示的问题。
  • 各级合计值在后端提前计算,前端直接展示即可,避免前端重复计算带来的性能开销和逻辑错误。

内容的提问来源于stack exchange,提问作者MelB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:45:29