将C#中的扁平数据库结果集转换为分层对象集合

7
我有一个数据库查询,返回扁平格式的分层数据。例如客户、订单和订单项(只是一个例子,我的数据不同)。如何将其转换为分层对象集合,即每个客户对象都有一个订单对象集合,每个订单对象都有一个订单项对象集合的客户对象集合?是循环遍历每个项目并手动构建对象层次结构,还是有更好的方法来实现这一点?我没有使用LINQ。我从SQL服务器数据库存储过程中获取数据。 编辑:我不使用LINQ从数据库检索数据,但如果可以将其转换为所需格式,则可以使用它来操作数据,如果这解决了问题。
编辑:样本数据看起来像这样(通过连接客户、订单和订单项表检索)(对于糟糕的格式化表示感到抱歉,我不知道如何在编辑器中格式化)

CustId CustName OrderId OrderName OrderItemId OrderItemName
C1 Cust1 O1 Order1 OI1 OrderItem1
C1 Cust1 O1 Order1 OI2 OrderItem2
C1 Cust1 O2 Order2 OI3 OrderItem3
C1 Cust1 O2 Order2 OI4 OrderItem4
C2 Cust2 O3 Order3 OI5 OrderItem5
C2 Cust2 O3 Order3 OI6 OrderItem6
C2 Cust2 O4 Order4 OI7 OrderItem7
C2 Cust2 O4 Order4 OI8 OrderItem8


你是通过一个查询还是一个结果集选择这些数据? - benwasd
是的,我会在一个查询中选择数据,而不想为每个父级单独进行数据库调用以获取子项。 - RKP
那么,你如何区分顾客、订单和订单项? - BitKFu
@BitKFu,请检查样本数据。 - RKP
3个回答

3

首先,结果集必须按照正确的顺序排列。

这意味着客户必须在订单之前出现,并且它们必须在结果集中出现在订单项之前。

排序:客户 -> 订单 -> 订单项

有了这个知识,你只需要遍历集合一次。

元代码:

foreach (item in resultset)
{
  // Build a customer and order dictionary
  if (!CustomerDictionary.Contains(item.Customer.Id)
     CustomerDictionary.Add(item.Customer.Id, item.Customer)

  if (!OrderDictionary.Contains(item.Order.Id)
     OrderDictionary.Add(item.Order.id, item.Order)

  // Now add the association      
  var customer = CustomerDictinoary[item.Customer.Id];
  customer.AddOrder(item.Order);

  var order = OrderDictinoary[item.Order.id];
  order.AddOrderItem(item.OrderItem);
}

我添加了示例数据,希望现在清楚了,上述解决方案对于示例数据不适用。谢谢。 - RKP
我调整了这个例子。但是请注意:这只是元代码,所以如果不进行一些更改,它无法编译。 - BitKFu

2
我建议使用映射工具,特别是ValueInjecter。ValueInjecter支持数据的解析。
你使用ValueInjecter的方法类似于:
var unflat = new Foo();
unflat.InjectFrom<UnflatLoopValueInjection>(flat);

这是一个“取消压扁”的示例的详细信息,请点击此处

0
你没有说明你是如何使用它的(也许是绑定到了知道关系的控件上?),但如果你必须使用ADO.NET,那么将结果放入DataSet中的不同表格,并添加定义表格之间关系的数据关系。这基本上就像数据库中的外键引用一样工作,而知道关系的控件将会利用这些关系。

我没有将这些数据绑定到任何控件,而是由某些其他组件使用,这些组件期望数据作为一组具有父子关系的对象进行处理。 - RKP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接