2011-02-14 18 views
5

[Nota después de la respuesta: en realidad estoy consultando en objetos de memoria y es por eso que ToTraceString no funciona. Añadí esto para ahorrarle al lector el tiempo potencial de leer mi larga publicación].Trace LINQ cuando se utilizan uniones

Estoy usando un comando ToTraceString al intentar inspeccionar cómo terminan buscando mis consultas LINQ. Sin embargo, hoy mi consulta tiene un poco complicado, que implica una join y, de repente, me sale este error al intentar efectuar el seguimiento de mi cadena:

No se puede convertir objeto de tipo 'd__7a`1 [EGSLanguageProviderShared.DTODataType] 'para escribir' System.Data.Objects.ObjectQuery '.

Mi consulta, y la posterior invocación de ToTraceString es la siguiente (tenga en cuenta que se debe hacer referencia a System.Data.Entity para que esto funcione). Ambos objetos que estoy consultando (langDTs y langInstructionsAVDTs) son objetos de Entity Framework (.Net 3.5) de la misma base de datos. La cláusula My Where (== av.InstructionAVKey) usa una clase simple Value Collection, nada que ver allí.

 IEnumerable<DTODataType> dts = 
      (from langDT in langDTs 
      join langIAVDT in langInstructionsAVDTs 
      on langDT.DataTypeKey equals langIAVDT.DataTypeKey 
      where langIAVDT.InstructionAVKey == av.InstructionAVKey 
      select langDT).Distinct(); 
     var sql = ((System.Data.Objects.ObjectQuery)dts).ToTraceString(); 

¿Alguna idea sobre cómo podría ver la traducción de LINQ de esta unión? :: -). Observé que System.Data.Objects tiene más tipos de consultas, pero no puedo obtener ninguno de los que parecen más relevantes para este caso, para que funcionen.

de editar posteriormente:

Como se recomienda, he intentado cambiar el IEnumerable en IQueryable pero que dio lugar a un error de compilación tipo de incompatibilidad :: - /.

Después de hacer una conversión explícita, que tiene el mismo error, pero en tiempo de ejecución (1 Unable to cast object of type '<DistinctIterator>d__7a1[EGSLanguageProviderShared.DTODataType]' to type 'System.Linq.IQueryable [EGSLanguageProviderShared.DTODataType]''.)

código adicional: mis objetos langDTs y langInstructionsAVDTs son:

List<DTOInstructionActiveValueDataType> langInstructionsAVDTs = CurrentLPInstructionManager.GetInstructionsActiveValuesDataTypes((from avKey in langInstructionsAVs select avKey.InstructionAVKey).Distinct().ToArray()); 

List<DTODataType> langDTs = _LPDataTypeManager.GetDataTypes((from dt in langInstructionsAVDTs orderby dt.DataTypeKey select dt.DataTypeKey).Distinct().ToArray()); 

Por lo tanto, estos objetos se consultan inmediatamente porque son Listas :: -). En cuanto a DTODataType y DTOInstructionActiveValueDataType, son simples Value Collection Classes, simplemente Public Properties, eso es todo.

incluso editar TARDE

puedan ser de interés que en su raíz, los objetos que estoy usando se declaran de hecho, como ObjectQuery de vuelta en la capa más profunda (Entity Framework):

public global::System.Data.Objects.ObjectQuery<instructions> instructions 

Sin embargo, a medida que traigo los datos de la capa de acceso a datos, los convierto en objetos de transferencia de datos (las clases con prefijo DTO que siguen viendo), que son simples Value Collection Classes (un mapa de propiedad por propiedad de la entidad) Objetos que utilizo para mantener el Modelo de Datos completamente separado de e Ver y también para ejecutar cualquier postproceso de datos en el lado de la Presentación).

+2

suelo usar LINQPAD para este propósito ... tiene una buena característica que hace esto ... (haz clic en el icono de lambda en el panel de resultados) –

+0

mira mi edición - necesito un poco más de código en tu pregunta. –

+0

Ver mi segunda respuesta. –

Respuesta

2

Según su edición posterior, está claro que simplemente está consultando y uniendo en las colecciones de memoria. Es por eso que no puedes convertir a ObjectQuery, y esa es la razón por la que no puedes declarar que la consulta es del tipo IQueryable<T>.

En otras palabras, no hay forma de hacer un volcado del SQL que se está emitiendo, porque no se está emitiendo SQL. Una vez que convirtió sus datos a su colección de DTO en memoria, se desconectó de su base de datos y todas sus consultas se convirtieron en consultas de linq a objetos sin que se generara el T-SQL correspondiente.

+0

Ummm ... disculpa por hacerte molestar sobre esto, entonces :: -). ¿Esto significa que no hay manera de encontrar de alguna manera lo que está sucediendo cuando consulto esos objetos? Estaba tratando de ver por qué obtengo un determinado resultado en un caso determinado, y necesitaba una forma de ver de dónde provienen los datos. Como un "Stack Trace" pero para LINQ. Ok, sí, estoy consultando colecciones en memoria, pero ¿hay alguna manera de ver exactamente cómo se están formando las colecciones en un solo comando? – Axonn

+0

¿Funcionó? Me divertí mucho respondiendo esto :) En cuanto a tu nueva pregunta, no sé. Publique una nueva pregunta que le pregunte específicamente y esperemos que haya un experto en linqto-objects que pueda ayudarlo (probablemente lo haya). Publique un enlace a la pregunta aquí; Estoy interesado en la respuesta yo mismo. –

5

En lugar de escribir su variable como IEnumerable<DTODataType> intente IQueryable<DTODataType>, o incluso var.

supongo en algún lugar existe la silla eléctrica consulta, y los resultados se almacenan como IEnumerable, y por lo tanto ya no es capaz de ser echado como ObjectQuery

EDITAR

¿Puede usted ampliar su fragmento de código para mostrar fueron ambos langDTs y vienen lasngInstructionsAVDTs?

+0

¡Bingo! Como lo ha declarado como IEnumerable, el ORM está ejecutando la consulta de inmediato. El resultado no es un ObjectQuery y no se puede convertir a ObjectQuery y, por lo tanto, no puede invocar a ToTraceString. –

+0

¿Estás seguro? Acabo de probar una consulta que se declaró como IEnumerable y no ejecutó la consulta en L2S, ni en EF4. Supongo que su consulta se está ejecutando * en algún lugar *, pero no creo que sea porque lo declaró como IEnumerable. Me interesaría ver qué son langDTs y landInstructionsAVDTs. ¿Están * ellos * declarados como IEnumerable? –

+0

En el marco de entidad si asigna una comprensión de consulta a un IEnumerable, la consulta se ejecuta inmediatamente. Supongo que está usando EF porque está usando ObjectQuery. Sin embargo, solo lo he usado en EF1, quizás hayan cambiado el comportamiento en EF4. –

Cuestiones relacionadas