2012-06-18 7 views
7

Tengo la siguiente consulta LINQ:¿Por qué LINQ-to-Entities coloca esta consulta en una sub selección?

var queryGroups = (from p in db.cl_contact_event 
        select new Groups { inputFileName = p.input_file_name }).Distinct(); 

que se traduce en lo siguiente cuando se ejecuta:

SELECT 
[Distinct1].[C1] AS [C1], 
[Distinct1].[input_file_name] AS [input_file_name] 
FROM (SELECT DISTINCT 
     [Extent1].[input_file_name] AS [input_file_name], 
     1 AS [C1] 
     FROM [mel].[cl_contact_event] AS [Extent1] 
) AS [Distinct1] 

Ahora estoy bastante seguro de que la razón hay un sub-select es porque tengo la consulta LINQ base rodeada por() y luego realizar .Distinct() pero no sé lo suficiente acerca de LINQ para estar seguro de esto. Si ese es el caso, ¿hay alguna manera de reestructurar/codificar mi consulta para que no ocurra una sub selección?

Sé que probablemente parezca que estoy aquí solo, pero tengo curiosidad.

+0

¿Es eso [tag: linq-to-sql], [tag: linq-to-entities] o [tag: linq-to-nhibernate]? –

+0

@DannyVarod linq-to-entities Creo que desde que estoy usando EF4 estoy consultando una base de datos de Sybase. – Kittoes0124

+0

En ese caso, cambie la etiqueta que ha utilizado y actualice el título de la pregunta en consecuencia. –

Respuesta

4

En esto sospecho que la causa real de la subconsulta es el constructor de tipo anónimo. Como no está seleccionando una entidad conocida, sino un objeto arbitrario construido a partir de otros valores de entidad, el analizador EF debe asegurarse de que puede producir el conjunto exacto de campos, ya sea desde una sola tabla, tablas combinadas, campos calculados, otros subconsultas, etc. El analizador de árbol de expresiones es muy bueno para escribir sentencias de SQL a partir de consultas LINQ siempre que sea posible, pero no es omnisciente. Procesa las consultas de una manera sistemática, que siempre producirá resultados correctos (en el sentido de que obtienes lo que pediste), aunque no siempre resultados óptimos.

En cuanto a la reescritura de la consulta para eliminar la selección secundaria, primero desactive: no veo una forma obvia de hacerlo que elimine el tipo anónimo y produzca resultados correctos. Más importante aún, sin embargo, I no molestaría. Los servidores SQL modernos como Sybase son muy inteligentes, a menudo más inteligentes que el desarrollador, y muy buenos para producir un plan de consulta óptimo a partir de una consulta. Además de eso, a EF le encantan las subconsultas, porque son muy buenas formas de escribir consultas complejas de forma automática. A menudo los encuentras incluso cuando tu consulta LINQ no apareció usándolos. Intentar eliminarlos todos de sus consultas se convertirá rápidamente en un ejercicio inútil.

+0

Gracias por la excelente y detallada respuesta. Solo quería asegurarme de no cometer ningún error obvio. – Kittoes0124

4

No me preocuparía en absoluto esta situación en particular. SQL Server (y muy probablemente cualquier base de datos empresarial) optimizará de todos modos la declaración Select externa. Me atrevería a teorizar que la razón por la cual se genera esta declaración SQL es porque esta es la declaración más genérica y reutilizable. Desde mi experiencia, esto siempre ocurre en Distinct().

Cuestiones relacionadas