60 votes

Frapper le 2100 limite de paramètre (SQL Server) lors de l'utilisation de Contains()

from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME

depts est une liste (IEnumerable<int>), du ministère de l'ids

Cette requête fonctionne très bien jusqu'à ce que vous passez une grande liste (disons, autour de 3000 dept id) .. alors, j'obtiens cette erreur:

Les entrants (tabular data stream) appel de procédure distante (RPC) du protocole de flux est incorrect. Trop de paramètres ont été fournis dans cette demande de RPC. Le maximum est de 2100.

J'ai changé ma requête:

var dept_ids = string.Join(" ", depts.ToStringArray());
from f in CUSTOMERS
where dept_ids.IndexOf(Convert.ToString(f.DEPT_id)) != -1
select f.NAME

à l'aide de IndexOf() correction de l'erreur, mais fait la requête lente. Est-il un autre moyen pour résoudre ce problème? merci beaucoup.

21voto

Marc Gravell Points 482669

Comment sur comme (dont les lots en morceaux maniables). Les autres (non-LINQ) options CSV et un "split" de l'UDF, et la table des paramètres (dans SQL2008).

15voto

ADM-IT Points 51

Ma solution (Guides -> Liste des 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;

6voto

Joel Potter Points 12759

Pourquoi ne pas écrire la requête sql et de joindre votre entité?

Il a été un certain temps depuis que j'ai travaillé dans Linq, mais va ici:

IQuery q = Session.CreateQuery(@"
         select * 
         from customerTable f
         where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);

Bien sûr, vous devez les protéger contre les injections, mais cela ne devrait pas être trop dur.

1voto

jpierson Points 3871

Vous voulez vérifier la LINQKit projet depuis l'intérieur, quelque part, est une technique de dosage de tels états pour résoudre ce problème. Je crois que l'idée est d'utiliser le PredicateBuilder pour briser la collection locale dans les petites formes de packets mais je n'ai pas revu la solution en détail, car j'ai plutôt été à la recherche d'un moyen plus naturel pour gérer cela.

Malheureusement, il ressort de la réponse de Microsoft à ma suggestion pour résoudre ce problème qu'il n'existe pas de plans pour avoir cette abordées .NET Framework 4.0 ou encore les service packs ultérieurs.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984

Mise à JOUR:

J'ai ouvert une discussion quant à savoir si cela allait être fixé pour LINQ to SQL ou le ADO.NET Entity Framework sur les forums MSDN. Veuillez voir ces messages pour plus de renseignements sur ces sujets et voir la solution temporaire que j'ai trouvé avec l'aide de XML et SQL UDF.

1voto

Roman O Points 312

J'ai eu le même problème, et j'ai deux solutions pour y remédier.

  1. Se croisent méthode
  2. rejoindre sur Id

Pour obtenir des valeurs qui ne sont PAS dans la liste, j'ai utilisé à l'Exception de la méthode OU de la jointure gauche.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X