c# datatable -有效地从数据表中为每个主记录选择详细记录

本文关键字:记录 选择 datatable 有效地 数据表 | 更新日期: 2023-09-27 18:02:05

我有一个主数据表,其中包含按发票#排序的发票记录。我还有另一个数据表,其中包含所有发票记录的详细信息(行项信息),按发票编号&行项目编号

如何从这两个表中有效地创建发票对象数组?对我来说,它看起来像是创建嵌套的For循环。外部for循环遍历orders表,内部for循环遍历行项表

我将保留一个保存当前发票#的临时标识符,一旦它在嵌套的for循环中找到不同的发票#,它将退出内部循环。

下面是我要做的伪代码

long currentInvoiceNumber=-1;  
int CurrentJCounter=0;
for(int i=0;i<MasterTable.Rows.Count;i++)       
{
    currentInvoiceNumber=MasterTable.Rows[i]["invoiceno"];
    Order oOrder = new Order();
   for(int j=CurrentJCounter;j<ItemDetailsTable.Row.Count;j++)
    {
         if(currentInvoiceNumber!=ItemDetailsTable.Rows[j]["invoiceno"])
          {
                 currentJCounter = j;
                break;
          }
          else
          {
            oOrder.AddItem(ItemDetailsTable.Rows[j]);
           }
    } 
    lstOrders.Add(oOrder);
} 

我必须提高应用程序的性能,我认为肯定有比这更好的方法。请建议

谢谢,Sveerap

c# datatable -有效地从数据表中为每个主记录选择详细记录

为了改进,您应该用感兴趣的字段排序第二个表,这是内部循环目标表(ItemDetailsTable)。当然,它会产生负面影响,但可以避免在大于/小于条件下不必要的内部循环。

我不知道是否,如果你使用LINQ对象/数据集,它将自动应用或不

方法A:
您可以使用LINQ确定发票的所有行列表,如:

var invoiceRows = (from r in ItemDetailsTable.Rows where r["invoiceno"].Equals(currentInvoiceNumber) select r);

(请注意,我现在还没有对此进行测试-您可能需要稍微摆弄一下LINQ语句,或者可能必须首先使用类型化数据集)

然后你可以遍历结果:

foreach (var invoiceRow in invoiceRows)
{
    oOrder.AddItem(invoiceRow);
}

然而,我不知道这是否会提高性能-它可能在阅读代码时"看起来"更优雅,然而;-)

至于退出内部循环:是否给定ItemDetailsTable行按发票编号"排序"?如果不是,如果发票B的一行位于发票A的两行之间,则可能会丢失发票A的一些行,如

所示。
Row 1 for invoice A
Row 2 for invoice A
Row 1 for invoice B
Row 3 for invoice A
Row 2 for invoice B
...

方法B
另一种方法可能如下:声明一个字典,以发票号作为键,如

Dictionary<string, Order> orderList = new ...;
然后,只迭代:
for (int j = 0; j < ItemDetailsTable.Row.Count; j++)
{
   if (!orderList.ContainsKey(ItemDetailsTable.Row[j]["invoiceno"]))
       orderList[ItemDetailsTable.Row[j]["invoiceno"]] = new Order();
   Order oOrder = orderList[ItemDetailsTable.Row[j]["invoiceno"]];
   oOrder.AddItem(ItemDetailsTable.Rows[j]);
}

最后,您可以通过键(发票号)或直接使用字典的值集合访问所有发票。

编辑
作为方法b的注释:

最后,字典可能不包含MasterTable中的所有发票号码-如果没有发票号码行,则不会添加任何条目。您可以通过在迭代行之前为MasterTable中的每个发票号添加一个条目来解决这个问题。

此外,字典最终可能包含不在MasterTable中的发票号。这些不会包含在嵌套循环方法中。通过在迭代行之前在单独的循环中添加发票号,然后修改我的代码示例,这样如果发票号尚未在字典中,则不会在字典中创建新项,您还可以防止这种情况。