我有一个主数据表,其中包含按发票#排序的发票记录。我还有另一个数据,其中包含所有那些按发票编号&和发票编号分类的发票记录的详细信息(行项目信息)。订单项号
如何从这两个表中有效地创建发票对象数组。对我来说,它看起来像创建嵌套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);
}
我必须提高appln的性能,我认为肯定会有比这更好的方法。请建议
谢谢, Sveerap
答案 0 :(得分:0)
要改进,您应该使用感兴趣的字段订购第二个表,这是内部循环目标表(ItemDetailsTable
)。当然,它会产生负面影响,但能够避免在条件上出现不必要的内部循环 - 大于/小于。
我不知道,如果您使用LINQ to Object / DataSet,它是否会自动应用。
答案 1 :(得分:0)
方法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
中的发票号。这些不会包含在嵌套循环方法中。通过在迭代行然后修改我的代码示例之前在单独的循环中添加发票编号,以便如果发票编号尚未出现在字典中,则不会在字典中创建新项目,您也可以阻止此操作。