martes, 12 de marzo de 2013

LINQ: IN (subquery)

Usar una subconsulta en un operdor IN es algo muy común para un programador, pero ¿Por qué es tan difícil encontrar un ejemplo claro de esto para LINQ to Entities?

Luego de darme a la tarea de buscar la solución para implentar el operador IN (subquery) con LINQ to Entities encontré este enlace http://stackoverflow.com/questions/3477918/linq-subquery-in. La solución es muy sencilla, pero me sorpendí porque en lugar de ver IN (subquery) ví un EXISTS(subquery) en la sentencia.

Eemplo:

LINQ
var subquery = from a in Bitacoras
 where a.env_numero == 5
 select a.asig_codigo;

var query = from b in Asignacions
 where subquery.Contains(b.asig_codigo)
 select b.asig_codigo;

T-SQL generado
SELECT 
[Extent1].[asig_codigo] AS [asig_codigo]
FROM [dbo].[Asignacion] AS [Extent1]
WHERE  EXISTS (SELECT 
 1 AS [C1]
 FROM [dbo].[Bitacora] AS [Extent2]
 WHERE (5 = [Extent2].[env_numero]) AND ([Extent2].[asig_codigo] = [Extent1].[asig_codigo])
)

No fue el EXISTS(subquery) lo que me sorprendió, es preferible usar el operador EXISTS en lugar de IN por que el primero tiene un mejor rendimiento. Lo que realmente me sorprendió es ver que LINQ to Entities generó una sentencia T-SQL optimizada para manejar grandes volúmenes de datos.

Sucede que el concepto que tengo es que para un proyecto sencillo, sin preocupción alguna, puedes hacer todas tus consultas con LINQ to Entities, pero es  muy probable que un futuro el volumen de datos crezca a niveles considerables y halla que trasladar ciertas consultas a procedimientos almacenados aplicando técnicas de optimización.

Ahora tendré toda confianza de usar consultas de LINQ parecidas a la anterior.

Para finalizar les dejo un ejemplo de LINQ to Entities usando el operador IN, pero con volores conocidos.

Ejemplo:

LINQ
var ids = new int[]{1,2,3,4,5};

var q = from b in Envios
  where ids.Contains(b.env_numero)
  select b;

T-SQL generado
SELECT 
[Extent1].[env_numero] AS [env_numero], 
[Extent1].[gtor_codigo] AS [gtor_codigo], 
[Extent1].[env_fecha] AS [env_fecha], 
[Extent1].[env_fecha_fin] AS [env_fecha_fin]
FROM [dbo].[Envio] AS [Extent1]
WHERE [Extent1].[env_numero] IN (1,2,3,4,5)

No hay comentarios:

Publicar un comentario

´