Linq:使用多个嵌套组获取内部对象的小计

如何解决Linq:使用多个嵌套组获取内部对象的小计

我需要从从SQL存储过程检索的数据集中创建一些报告。这是数据的表示形式:

+--------------+-------------------+-----------------+--------------------+
| CustomerName | CustInventoryAcct | ProductCategory | ProductSubCategory |
+--------------+-------------------+-----------------+--------------------+
| ABC          |             12345 | Books           | Fiction            |
| ABC          |             12345 | Books           | Fiction            |
| ABC          |             12345 | Books           | Non-Fiction        |
| ABC          |             67890 | Magazines       | Sports             |
+--------------+-------------------+-----------------+--------------------+

数据集还包括许多与我为简洁起见省略的实际产品相关的数据字段-以上是我需要分组的四个条件。

报告需要对这四个字段中的每个字段进行分组,因此使用上表,输出将如下所示:

Customer Header: ABC
    Inventory Header: 12345
        Category Header: Books
            Sub Category Header: Fiction
                Detail rows for each of the items in this group (2 using the sample data above)
            Sub Category Footer: Fiction (Item Count : 2)
            Sub Category Header: Non-Fiction
                Detail row
            Sub Category Footer: Non Fiction (Item Count: 1)
        Category Footer: Books (Item Count: 3)
    Inventory Footer: 12345 (Item Count: 3)
    Inventory Header: 67890
        Category Header: Magazines
            Sub Category Header: Sports
                Detail row
            Sub Category Footer: Sports (Item Count: 1)
        Category Footer: Magazines (Item Count: 1)
    Inventory Footer: 67890 (Item Count: 1)
Customer Footer: ABC (Item Count: 4)

我有一个用于分组的Linq查询(不确定这是否是最好的方法):

var groupedData = rawData
    .GroupBy(x => new { x.ProductSubCategory,x.ProductCategory,x.CustInventoryAcct,x.Customer })
    .GroupBy(x => new { x.Key.ProductCategory,x.Key.CustInventoryAcct,x.Key.Customer })
    .GroupBy(x => new { x.Key.CustInventoryAcct,x.Key.Customer })
    .GroupBy(x => new { x.Key.Customer })

我使用嵌套的foreach循环来构建报告结构:

foreach (var customer in groupedData)
{
    GenerateHeader(customer.Key);
    foreach (var custInventory in customer)
    {
        GenerateHeader(custInventory.Key.CustInventoryAcct);
        foreach(var category in custInventory)
        {
            GenerateHeader(category.Key.ProductCategory);
            foreach(var subCategory in category)
            {
                GenerateHeader(subCategory.Key.ProductSubCategory);
                foreach (var item in subCategory)
                    // Populate detail rows
                // Generate footer
             }
             // Generate footer
        }
        // Generate footer
    }
    // Generate footer    
}
// Generate footer

这部分工作得很好-问题是当我尝试获取每个页脚的项目计数时。我可以使用Count()来获得上一个嵌套级别(SubCategory)的项目计数,但是如果我尝试在更高的级别上进行操作,则可以预测地获得该级别的组数,而不是底部的基础项目层次结构。我不知道如何向下钻取,因此可以为每个嵌套级别创建小计。

我可以通过使用一些int计数器来解决这个问题,但是我想知道Linq中是否有办法做到这一点。我遇到的困难使我怀疑我的分组查询是否不是处理Linq中嵌套组的正确方法。

我已经阅读了很多有关使用GroupBy的SO解答和文章,但仍然无法弄清楚-有人可以帮助我了解完成我要完成的工作的最佳方法吗?

解决方法

尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication169
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("CustomerName",typeof(string));
            dt.Columns.Add("CustInventoryAcct",typeof(string));
            dt.Columns.Add("ProductCategory",typeof(string));
            dt.Columns.Add("ProductSubCategory",typeof(string));

            dt.Rows.Add(new object[] { "ABC","12345","Books","Fiction" });
            dt.Rows.Add(new object[] { "ABC","Non-Fiction" });
            dt.Rows.Add(new object[] { "ABC","67890","Magazines","Sports" });

            foreach(var name in dt.AsEnumerable().GroupBy(x => x.Field<string>("CustomerName")))
            {
                Console.WriteLine("Customer Header: {0}",name.Key);
                foreach (var header in name.GroupBy(x => x.Field<string>("CustInventoryAcct")))
                {
                    Console.WriteLine("    Inventory Header: {0}",header.Key);
                    foreach (var category in name.GroupBy(x => x.Field<string>("ProductCategory")))
                    {
                        Console.WriteLine("        Category Header: {0}",category.Key);
                        foreach (var subCategory in name.GroupBy(x => x.Field<string>("ProductSubCategory")))
                        {
                            Console.WriteLine("            Sub Category Header: {0}",subCategory.Key);
                            foreach (DataRow row in subCategory)
                            {
                            }
                            Console.WriteLine("            Sub Category Footer: {0}",subCategory.Key);
                        }
                        Console.WriteLine("        Category Footer: {0}",category.Key);
                    }
                    Console.WriteLine("    Inventory Footer: {0}",header.Key);
                }
                Console.WriteLine("Customer Footer: {0}",name.Key);
            }
            Console.ReadLine();
        }
    }
  
}
,

我建议您不要先进行Group的四个级别的操作,而要逐步进行。这样,您可以Count()每个组为您提供总计:

foreach(var customer in rawData.GroupBy(x => new { x.ProductSubCategory,x.ProductCategory,x.CustInventoryAcct,x.CustomerName }))
{
    Console.WriteLine(customer.Key.CustomerName);
    foreach(var inventory in customer.GroupBy(x => new { x.ProductCategory,x.CustomerName }))
    {
        Console.WriteLine($"\t{inventory.Key.CustInventoryAcct}");
        foreach(var category in inventory.GroupBy(x => new { x.CustInventoryAcct,x.CustomerName }) )
        {
            // etc
        }           
        Console.WriteLine($"\tNumber of items: {inventory.Count()}");   
    }
    Console.WriteLine($"Number of items: {customer.Count()}");
}

实时示例:https://dotnetfiddle.net/YtShT3

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res