from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME
depts
est une liste (IEnumerable<int>
) des identifiants de département
Cette requête fonctionne correctement jusqu'à ce que vous passiez une longue liste (disons environ 3000 ID de service) ..
Le flux de protocole d'appel de procédure distante TDS (Tabular Data Stream) entrant est incorrect. Trop de paramètres ont été fournis dans cette demande RPC. Le maximum est 2100.
J'ai changé ma requête en:
var dept_ids = string.Join(" ", depts.ToStringArray());
from f in CUSTOMERS
where dept_ids.IndexOf(Convert.ToString(f.DEPT_id)) != -1
select f.NAME
utiliser IndexOf()
corrige l'erreur mais ralentit la requête. Y a-t-il un autre moyen de résoudre ce problème? Merci beaucoup.
Ma solution (Guides -> Liste de 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;
Pourquoi ne pas écrire la requête en SQL et attacher votre entité?
Cela fait longtemps que je n'ai pas travaillé à Linq, mais voici:
IQuery q = Session.CreateQuery(@"
select *
from customerTable f
where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);
Bien sûr, vous devrez vous protéger contre les injections, mais cela ne devrait pas être trop difficile.
Vous voudrez peut-être consulter le projet LINQKit , car il existe quelque part une technique permettant de regrouper de telles instructions pour résoudre ce problème. Je pense que l'idée est d'utiliser PredicateBuilder pour diviser la collection locale en fragments plus petits, mais je n'ai pas examiné la solution en détail, car je recherchais plutôt un moyen plus naturel de gérer cela.
Malheureusement, il ressort de la réponse de Microsoft à ma suggestion de corriger ce problème qu’aucun plan n’a été prévu pour que cela soit adressé à .NET Framework 4.0 ou même aux service packs ultérieurs.
https://connect.Microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984
METTRE À JOUR:
J'ai ouvert des discussions pour savoir si cela allait être résolu pour LINQ to SQL ou pour le ADO.NET Entity Framework sur les forums MSDN. Veuillez consulter ces messages pour plus d'informations sur ces sujets et pour voir la solution de contournement temporaire que j'ai proposée à l'aide de XML et d'un fichier UDF SQL.
Vous pouvez toujours partitionner votre liste de dépôts en ensembles plus petits avant de les transmettre comme paramètres à l'instruction IN générée par Linq. Vois ici:
Diviser un grand IEnumerable en un plus petit IEnumerable d'une quantité fixe d'élément