如何使用Linq to SQL在C#中将扁平对象转换为嵌套子对象
问题解决:扁平数据转嵌套JSON结构
现有代码的核心问题
- Root对象创建逻辑错误:外层GroupBy后直接为每个分组生成Root,最终得到
IEnumerable<Root>而非单个Root对象,不符合目标JSON的顶层结构。 - 分组层级引用错误:处理CounterSale时错误引用外层Location分组集合,而非当前分组内的元素;创建CounterSale属性时误用循环变量
l的字段,而非分组的Key和分组内的统一值。 - Part集合范围错误:Part集合取了整个Location分组的所有元素,而非当前Invoice分组下的零件数据。
修正后的代码
string connectionString = "data source=localhost;initial catalog=ASPENDV;integrated security=true;"; var result = new List<DataClass>(); using (SqlConnection connection = new SqlConnection(connectionString)) { result = connection.Query<DataClass>("sp_TestData", commandType: System.Data.CommandType.StoredProcedure).ToList(); } // 转换逻辑 var root = new Root { Location = result // 第一层级:按LocationId分组 .GroupBy(d => d.LocationId) .Select(locationGroup => new Location { LocationID = locationGroup.Key, DBSIdentifier = locationGroup.First().DBSIdentifier, DBSVersion = locationGroup.First().DBSVersion.ToString(), // 类型转换匹配模型 InterfaceVersion = "2.0", // 目标JSON固定值 LanguageCode = locationGroup.First().LanguageCode, // 第二层级:当前Location分组内按InvoiceNumber分组 CounterSale = locationGroup .GroupBy(d => d.InvoiceNumber) .Select(invoiceGroup => new CounterSale { InvoiceNumber = invoiceGroup.Key, CreationTimestamp = invoiceGroup.First().CreationTimestamp, InvoiceTimestamp = invoiceGroup.First().InvoiceTimestamp ?? DateTime.MinValue, // 处理Nullable字段 // 第三层级:当前Invoice分组内的零件数据转Part集合 Part = invoiceGroup .Select(partData => new Part { PartNumber = partData.PartNumber, Description = partData.Description, // 注:DataClass未定义Quantity字段,若需填充需先在DataClass中添加对应字段 // Quantity = partData.Quantity?.ToString() }) .ToList() }) .ToList() }) .ToList() };
关键说明
- 直接创建单个Root对象,其Location属性为分组转换后的集合,完全匹配目标JSON的顶层结构。
- 分组内的统一字段(如Location的DBSIdentifier、CounterSale的CreationTimestamp)通过
First()获取,前提是同分组内这些字段值一致(需保证数据库返回的扁平数据符合该规则)。 - 层级严格对应:Location分组 → 每个Location内的Invoice分组 → 每个Invoice内的Part集合,完美复现目标JSON的嵌套结构。
- 处理了类型转换(DBSVersion从int转string)和Nullable字段的空值兜底逻辑。
内容的提问来源于stack exchange,提问作者Muhammad Kamran
相关产品推荐
相关产品推荐

