c# - 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()
,但如果我在更高级别尝试这样做,它可以预见地给我该级别的组数,而不是层次结构底部的基础项目。我不知道如何向下钻取,以便为每个嵌套级别创建小计。
我可以通过使用一些int
计数器来解决这个问题,但我想知道在 Linq 中是否有办法做到这一点。我遇到的困难让我想知道我的分组查询是否不是在 Linq 中处理嵌套组的正确方法。
我已经阅读了一堆关于使用的 SO 答案和文章,GroupBy
但仍然无法弄清楚 - 有人可以帮助我了解完成我想要做的事情的最佳方法吗?
解决方案
尝试以下:
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", "12345", "Books", "Fiction" });
dt.Rows.Add(new object[] { "ABC", "12345", "Books", "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();
}
}
}
推荐阅读
- python - 使用熊猫返回字符串列表
- azure-active-directory - 为 Azure AD 启用 AD 同步时提示用户单点登录
- php - PHP:在数组中选择表值?
- wxpython - 如何更改每个选项卡的列数?
- docker - 当容器在 localhost 接口上侦听时,Docker 端口转发不起作用
- carrierwave - 从 PWM 创建正值和负值
- kotlin - RxJava:运行一个可完成的列表,直到一个成功
- search - 是否有 amp-story 的搜索组件?
- python - 使用美丽的汤和硒问题进行刮擦
- node.js - 非 www 到 https://www