from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME
depts
ist eine Liste (IEnumerable<int>
) von Abteilungs-IDs
Diese Abfrage funktioniert gut, bis Sie eine große Liste übergeben (etwa um 3000 ID-IDs). Dann erhalte ich diesen Fehler:
Der RPC-Protokolldatenstrom für eingehende tabellarische Datenströme (TDS) ist falsch. In dieser RPC-Anforderung wurden zu viele Parameter angegeben. Das Maximum ist 2100.
Ich habe meine Anfrage geändert in:
var dept_ids = string.Join(" ", depts.ToStringArray());
from f in CUSTOMERS
where dept_ids.IndexOf(Convert.ToString(f.DEPT_id)) != -1
select f.NAME
mit IndexOf()
wurde der Fehler behoben, die Abfrage wurde jedoch langsam. Gibt es eine andere Möglichkeit, dieses Problem zu lösen? vielen Dank.
Meine Lösung (Guides -> List of Guid):
List<tstTest> tsts = new List<tstTest>();
for(int i = 0; i < Math.Ceiling((double)Guides.Count / 2000); i++)
{
tsts.AddRange(dc.tstTests.Where(x => Guides.Skip(i * 2000).Take(2000).Contains(x.tstGuid)));
}
this.DataContext = tsts;
Warum schreiben Sie die Abfrage nicht in SQL und hängen Ihre Entität an?
Es ist schon eine Weile her, seit ich in Linq gearbeitet habe, aber hier heißt es:
IQuery q = Session.CreateQuery(@"
select *
from customerTable f
where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);
Natürlich müssen Sie sich vor Injektionen schützen, aber das sollte nicht zu schwer sein.
Sie sollten sich das LINQKit-Projekt ansehen , da sich irgendwo eine Technik zum Bündeln solcher Anweisungen befindet, um dieses Problem zu lösen. Ich glaube, die Idee ist die Verwendung des PredicateBuilder, um die lokale Sammlung in kleinere Stücke zu unterteilen, aber ich habe die Lösung nicht im Detail geprüft, weil ich stattdessen nach einer natürlicheren Methode gesucht habe, um damit umzugehen.
Leider scheint es aus Microsofts Antwort auf meinen Vorschlag , um dieses Verhalten zu beheben, dass keine Pläne festgelegt wurden, um dies für .NET Framework 4.0 oder sogar nachfolgende Service Packs adressieren zu lassen.
https://connect.Microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984
AKTUALISIEREN:
Ich habe einige Diskussionen darüber eröffnet, ob dies für LINQ to SQL oder das ADO.NET Entity Framework in den MSDN-Foren behoben werden sollte. In diesen Beiträgen finden Sie weitere Informationen zu diesen Themen und die temporäre Problemumgehung, die ich mit XML und einer SQL-UDF gefunden habe.
Sie können Ihre Liste der Abteilungen immer in kleinere Mengen unterteilen, bevor Sie sie als Parameter an die von Linq generierte IN-Anweisung übergeben. Siehe hier:
Ein großes IEnumerable in ein kleineres IEnumerable mit einem festen Artikelbetrag teilen