Équivalent plus rapide de la clause SQL Server IN pour de nombreuses valeurs

J'utilise OrmLite .NET avec SQL Server 12.0. Je veux sélectionner des entités où une certaine colonne entière (pas la key primaire) a l'une des nombreuses valeurs, que j'ai dans un tableau. Une expression OrmLite comme ceci:

q => query.Where(r => myIntegers.Contains(r.TheColumn)) 

est traduit en

 WHERE "TheColumn" IN (1, 2, 3, ...) -- my integers 

Cela fonctionne bien avec ~ 100, mais expire avec 1000. Comment puis-je get le même effet avec une list plus grande? Puis-je passer un tableau à SQL Server en quelque sorte ou un paramètre de table?

Semblable à ce que @JoeTaras a commenté, vous pouvez mettre les valeurs acceptables dans une sous-requête, quelque chose comme;

 SELECT TheColumn from TheTable T INNER JOIN (SELECT * from (VALUES(1),(2),(3),(4)) as V1(value)) V ON T.TheColumn = V.value 

Dans OrmLite, vous pouvez créer une requête SQL brute dont vous avez besoin (par exemple, dans la réponse @Sam cd) et la passer à la méthode db.Select :

 ssortingng joinedIds = ssortingng.Join("),(", new List<int> {1, 2, 9}); ssortingng command = $"SELECT * from Employee AS E INNER JOIN (SELECT * from (VALUES( {joinedIds} )) as TV(value)) V ON E.Id = V.value"; List<Employee> employers = db.Select<Employee>(command); 

J'ai fini par utiliser une table temporaire pour cela, à savoir:

 CREATE TABLE #ParamTempTable (Id BIGINT NOT NULL PRIMARY KEY); INSERT INTO #ParamTempTable (Id) VALUES ((1), (2), (3)); SELECT * FROM MyTable WHERE Id IN (SELECT * FROM #ParamTempTable); DROP TABLE #ParamTempTable; 

Je le fais seulement quand j'ai plus de 1000 valeurs, sinon j'utilise juste SQL IN (1, 2, 3) .

Pour l'implémenter sur OrmLite, j'ai dû sous- SqlServerExpression<T> et replace VisitStaticArrayMethodCall et VisitEnumerableMethodCall pour changer la manière dont VisitEnumerableMethodCall gérait les expressions. Cette class stocke les commands pour créer et supprimer les tables temporaires séparément et je dois exécuter une command SqlCommand distincte pour chacune d'entre elles. ( CREATE TABLE ne fonctionne pas dans SqlCommand.ExecuteReader , malheureusement.) Cela a fini par être assez compliqué, mais cela fonctionne et est transparent pour l'appelant. Un avantage supplémentaire est que je pourrais éliminer les parameters en double, donc par exemple pour o => ids.Contains(o.FromId) || ids.Contains(o.ToId) o => ids.Contains(o.FromId) || ids.Contains(o.ToId) les ids list sont envoyés au server SQL une seule fois.