El problema del límite de 2100 parámetros no existe en EF.
He realizado una prueba en the AdventureWorks database (en SQL Express 2008 R2): Estoy tratando de obtener todos los productos donde ProductCategoryId
está en el rango de valores (1, 2, 3).
Usando LINQ, la generada WHERE
cláusula SQL tiene este aspecto:
WHERE [t0].[ProductCategoryID] IN (@p0, @p1, @p2)
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1]
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2]
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [3]
(que conduce a la cuestión número de parámetro max), mientras que con EF 4.0 se ve así:
WHERE [Extent1].[ProductCategoryID] IN (1,2,3)
A continuación, he probado esto con EF para obtener una lista de 3000 valores:
var categoryList = Enumerable.Range(1, 3000).Select(i => (int?)i).ToArray();
using (var aw = new AdventureWorksEntities())
{
var products = aw.Products
.Where(p => categoryList.Contains(p.ProductCategoryID))
.ToList();
}
Mientras esto es extremadamente ineficiente, funciona y produce el resultado esperado.
Sin embargo, también es posible utilizar el InRange
extensión provided by Marc Gravell con EF, utilizando también la LINQKit library, así:
using (var aw = new AdventureWorksEntities())
{
var products = aw.Products
.AsExpandable()
.InRange(p => p.ProductCategoryID, 1000, categoryList)
.ToList();
}
(la extensión AsExpandable
se define en LINQKit)
Esto produce el resultado esperado (ejecuta la consulta en fragmentos) y, dependiendo de la cantidad de elementos en la lista y el tamaño del fragmento, puede ser mucho más eficiente que la solución no fragmentada.
Crear una consulta que requiera más de 2100 elementos estáticamente definidos para la instrucción 'IN' (que es la parte del contador de' Contains') no parece una aproximación correcta. Tal operación debe manejarse completamente en DB sin necesidad de pasar datos del cliente. –
Entiendo su preocupación, pero ciertamente hay casos en los que * todos * los datos requeridos no estarán en la base de datos. Definitivamente hay alternativas para pasar una lista tan grande de parámetros, pero este simple resumen resulta extremadamente flexible para la forma en que nos gustaría usarlo (y el 99% del tiempo no será necesario usarlo). – Ocelot20