我可以使用泛型的力量来解决我的问题

时间:2009-06-26 06:32:43

标签: sql vb.net data-access-layer

我有一个奇怪的问题。我正在加载1k发票对象,首先在我的DAL中添加详细信息。我在这个项目上使用VB.NET。我能够得到发票标题就好了。当我开始加载每张发票的详细信息时,我在SQL Server上获得了超时。我将超时时间增加到5分钟,但仍然是相同的。如果我将发票数量减少到200,那就可以了。

这就是我正在做的事情



        //I already loaded the invoice headers. I am now iterating each invoice to get    it's detail
        For Each invoice As Invoice In invoices
            drInvoiceItems = DBSqlHelperFactory.ExecuteReader(CONNECTION_STRING, CommandType.StoredProcedure, "dbo.getinvoiceitem", _
                                                                                                       New SqlParameter("@invoicenumber", invoice.InvoiceNumber))
            While drInvoiceItems.Read()
                invoice.LineItems.Add(New InvoiceLine(drInvoiceItems("id"), drInvoiceItems("inv_id"), drInvoiceItems("prodid"), drInvoiceItems("name"), drInvoiceItems("barcode"), drInvoiceItems("quantity"), drInvoiceItems("costprice")))
            End While

        Next

        Return invoices

我知道由于迭代,我正在向DB发送1k连接。我无法使用一个select语句加载所有订单项,然后执行类似

的操作
For Each invoice As Invoice In invoices

  invoice.Items.Add(invoiceItems.Find(Function(i as InvoiceItem),i.InvoiceNumber = invoice.InvoiceNumber))

Next

使用上面的lambda函数时出错 错误1类型'System.Collections.Generic.List(Of BizComm.InvoiceLine)'的值无法转换为'BizComm.InvoiceLine'。 C:\ Projects \ BizComm \ InvoiceDAL.vb 75 35 BizComm

4 个答案:

答案 0 :(得分:1)

我在过去迭代项目时所做的一件事是对所有必要的读取活动使用相同的Connection对象。它似乎大大提高了性能。

我还会查看数据库以查看是否可以改进dbo.getinvoiceitem程序,或者是否可以编写另一个程序,该程序将为您提供一组发票的所有行项目(可能是按日期或客户/供应商)而不是一次只有一个标题。然后,您可以更有效地将迭代应用于发票集合,并将行添加到标题中。

您还可以检查@invoicenumber参数引用的列是否有有效索引。

答案 1 :(得分:1)

从您的代码中,您似乎没有关闭连接和数据区。看看您是否可以将您的连接和数据加载器放在USING语句中:

Using con As New SqlConnection(connectionString)
    ....
End Using

DBSqlHelperFactory打开一个连接,但由于在返回后需要连接,因此无法关闭它。我修改了代码,以便您打开一个连接并将其作为参数传递给DBSqlHelperFactory。

为了快速解决这些问题,我总是调试:

Max Pool Size=1;

添加到连接字符串的末尾。只要忘记关闭连接,这将很快发生错误。

答案 2 :(得分:0)

为什么要预先加载InvoiceItems?你不能按需加载它吗? 即,当您需要获取Items时,请在Invoice实例(myInvoice.GetItems

上调用方法

编辑:最好全面了解你想要做的事情。
是否真的需要获得所有发票?

答案 3 :(得分:0)

为什么不在单个查询中选择所需的所有发票的所有订单项。然后将结果分成多个发票对象?

Re:我如何在集合之间进行映射?

一个实现可能是:创建1000个贫血的Invoice对象,将它们放入从Id到Invoice的Dictionary中。然后,当您选择包含发票ID的行项目时,请查找贫血发票并将行添加到其中。