2009-06-26 2 views
0

Ich habe ein seltsames Problem. Ich lade 1k Rechnungsobjekte, Kopfzeile zuerst dann Details in meiner DAL. Ich verwende VB.NET für dieses Projekt. Ich bin in der Lage, die Rechnungsheader gut zu bekommen. Wenn ich die Details für jede Rechnung lade, erhalte ich eine Zeitüberschreitung bei SQL Server. Ich habe das Timeout auf 5 Minuten erhöht, aber immer noch das Gleiche. Wenn ich die Rechnungsanzahl auf 200 reduziere, funktioniert es gut. HierKann ich die Macht von Generics verwenden, um mein Problem zu lösen

ist, was ich tue

 


     //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 

Ich bin mir bewusst, dass ich 1k Verbindungen an die DB am Brennen aufgrund der Iterationen. Kann ich nicht mit einer select-Anweisung alle Positionen laden und dann wie etwas tun

For Each invoice As Invoice In invoices 

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

Next 

ich den Fehler whenusing der Lambda funcion oben Fehler 1 Der Wert des Typs ‚System.Collections.Generic.List erhalten (Of BizComm.InvoiceLine) 'kann nicht in' BizComm.InvoiceLine 'konvertiert werden. C: \ Projects \ BizComm \ InvoiceDAL.vb 75 35 BizComm

+0

Vielleicht sollten Sie den Titel neu formulieren. Ich sehe das nicht in Bezug auf Generika überhaupt ... –

Antwort

0

Warum InvoiceItems vorher laden? Kannst du es nicht auf Nachfrage laden?
das heißt, wenn Sie benötigen, um die Einzelteile zu erhalten, eine Methode auf Rechnung Instanz aufrufen (myInvoice.GetItems)

EDIT: Es ist besser, das vollständige Bild von dem zu verstehen, was Sie zu tun versuchen.
Ist es wirklich erforderlich, alle Rechnungen zu erhalten?

+0

Ich nedd, um die vollständige Liste zu einem anderen functon zu übergeben, der und EDI-Dokument produziert .... langer Prozess. –

+0

Wenn Sie eine Datei daraus erstellen möchten, warum gehen Sie über Invoice & InvoiceItems? Ich denke, dass Sie die Objektschicht in diesem Fall umgehen sollten. – shahkalpesh

0

Warum nicht alle Einzelposten für alle Rechnungen auswählen, die Sie in einer einzigen Abfrage benötigen. dann die Ergebnisse in mehrere Rechnungsobjekte aufteilen?

Betreff: Wie kann ich zwischen den Sammlungen zuordnen?

Eine Implementierung könnte sein: 1000 anemic Invoice-Objekt erstellen, chuck sie in einem Wörterbuch, das von ID zu Invoice geht. Wenn Sie die Werbebuchungen auswählen, denen Sie die Rechnungs-ID hinzufügen, suchen Sie die anämische Rechnung und fügen Sie die Zeile hinzu.

+0

Wie kann ich zwischen Sammlungen zuordnen? –

1

Eine Sache, die ich bei der Iteration von Elementen in der Vergangenheit gemacht habe, ist die Verwendung des gleichen Connection-Objekts für alle notwendigen Leseaktivitäten. Es scheint die Leistung stark zu verbessern.

Ich würde auch in der Datenbank sehen, ob die dbo.getinvoiceitem Prozedur verbessert werden kann, oder ob eine andere Prozedur geschrieben werden kann, die Ihnen alle Positionen für eine Gruppe von Rechnungen gibt (vielleicht nach Datum oder Kunde/Lieferant)) anstatt nur einen Header nach dem anderen. Dann können Sie Ihre Iteration effektiver auf die Rechnungserfassung anwenden und die Zeilen den Kopfzeilen hinzufügen.

Sie können auch überprüfen, ob ein effektiver Index für die Spalte vorhanden ist, den der Parameter @invoicenumber referenziert.

+0

Egal, was Sie tun, wenn der betreffende Algorithmus etwa 10.000 Rundreisen (durchschnittlich 10 Artikel pro Rechnung) erzwingt, wird es langsam sein. –

1

Aus Ihrem Code sieht es so aus, als würden Sie die Verbindungen und Datenreader nicht schließen. Sehen Sie, wenn Sie Ihre Verbindungen und Datareaders in einer USING-Anweisung platzieren können:

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

Die DBSqlHelperFactory eine Verbindung öffnet, kann es aber nicht schließen, da die Verbindung nach seiner Rückkehr benötigt wird. Ich würde den Code ändern, sodass Sie eine Verbindung öffnen und als Parameter an DBSqlHelperFactory übergeben.

Um schnell diese Probleme aufgreifen, habe ich immer debuggen mit:

Max Pool Size=1; 

bis zum Ende der Verbindungszeichenfolge hinzugefügt. Das wird schnell einen Fehler verursachen, wenn Sie vergessen, eine Verbindung zu schließen.

Verwandte Themen