2009-08-24 1 views
0

Ich habe den folgenden Code-Schnipsel:Erste Zeilen aus einer SQL-Tabelle ein Wörterbuch für: LINQ mit

var matchingAuthors = from authors in DB.AuthorTable 
          where m_authors.Keys.Contains(authors.AuthorId) 
          select authors; 

    foreach (AuthorTableEntry author in matchingAuthors) 
    { 
     .... 
    } 

wo m_authors ein Wörterbuch der „Autor“ Einträge enthalten ist, und DB.AuthorTable ist eine SQL-Tabelle. Wenn die Größe m_authors über einen bestimmten Wert geht (irgendwo um die 3000 Einträge Marke), erhalte ich eine Ausnahme:

System.Data.SqlClient.SqlException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. 
Too many parameters were provided in this RPC request. The maximum is 2100. 

Gibt es eine Möglichkeit, dies zu umgehen und arbeiten mit einer größeren Größe Wörterbuch bekommen? Gibt es alternativ eine bessere Möglichkeit, alle Zeilen in einer SQL-Tabelle abzurufen, in der ein bestimmter Spaltenwert für diese Zeile mit einem der Wörterbucheinträge übereinstimmt?

Antwort

2

LINQ to SQL verwendet eine parametrisierte IN Anweisung eine lokale Contains() auszuführen:

... 
WHERE AuthorId IN (@p0, @p1, @p2, ...) 
... 

So ist der Fehler, den Sie zu sehen sind, ist, dass SQL aus Parameter lief für Ihre Schlüssel zu verwenden. Ich kann mir zwei Möglichkeiten vorstellen:

  1. Wählen Sie die gesamte Tabelle und filtern Sie mit LINQ to Objects.

  2. Generieren eines Ausdrucksbaums von Ihren Schlüsseln: siehe Option 2 here.

0

Eine weitere Option ist zu überlegen, wie Sie m_authors füllen und ob Sie sich, dass in der Abfrage als Abfrageelement umfassen kann, so dass es in eine serverseitige Drehungen/subselect verbinden.

0

Je nach Ihren Anforderungen könnten Sie die Arbeit in mehrere kleinere Teile zerlegen (erste tausend, zweitausend usw.). Dies birgt gewisse Risiken, wenn Ihre Daten schreibgeschützt sind und sich häufig ändern etwas bessere Skalierbarkeit, als Tausende von Zeilen in einem großen Schluck zurück zu ziehen. Und wenn Ihre Daten teilweise bearbeitet werden können (d. H. Ohne das gesamte Set im Speicher zu haben), könnten Sie Chunks senden, die in einem separaten Thread bearbeitet werden sollen, während Sie den nächsten Chunk zurückziehen.

Verwandte Themen