2012-04-14 20 views
15

Hola tengo este trozo de código LINQLINQ Seleccionar primer

var fp = lnq.attaches.First(a => a.sysid == sysid).name; 

Cuando perfilado que genera el siguiente T-SQL

SELECT TOP (1) [t0].[sysid], [t0].[name], [t0].[att_size], [t0].[cid], [t0].[flags], [t0].[contents] 
FROM [lntmuser].[attach] AS [t0] 

La forma en que lo miro, se está volviendo como un selecto *, lo que hará que la consulta realice una exploración de tabla en lugar de usar un índice. Malo para el rendimiento.

¿Cómo podría seleccionar sólo la columna de nombre, como:

SELECT TOP (1)[t0].[name] FROM [lntmuser].[attach] AS [t0] 

Gracias de antemano


Editar: Vidrios quebrados perfiles Solución según se desee

SELECT TOP (1) [t0].[name] 
FROM [lntmuser].[attach] AS [t0] 
WHERE [t0].[sysid] = @p0 

Respuesta

25

Proyecto de la propiedad name antes de usar First() :

var fp = lnq.attaches.Where(a => a.sysid == sysid) 
        .Select(a => a.name) 
        .First(); 

Esto no cambia el uso de un índice sin embargo - para que su cláusula de Where es responsable (en su consulta inicial, el lambda que pasó a First()). Ambas consultas se benefician de un índice en la columna name, la segunda es simplemente más rápida porque solo se debe materializar un valor de columna.

+1

Sería curioso ver cómo se ve este código en Profiler. – dtown123

+0

@ dtown123 Sí, eso fue lo primero que hice jajaja, agregué el código en la respuesta. –

+0

@BrokenGlass Marcaré la respuesta en cuanto me permita agradecerle por su ayuda –