Trace LINQ when Joins are used
[Note After Answer: I am actually querying in memory-objects and that's why ToTraceString
doesn't work. I added this to save the reader potential time from reading my long post].
I'm using a ToTraceString
command when trying to inspect how my LINQ queries end up looking. However, today my query got a bit complicated, involving a join
and all of the sudden, I get this error when I try to Trace my String:
Unable to cast object of type 'd__7a`1[EGSLanguageProviderShared.DTODataType]' to type 'System.Data.Objects.ObjectQuery'.
My Query, and subsequent invocation of ToTraceString
is as fol开发者_JAVA技巧lows (note that System.Data.Entity has to be referenced in order for this to work). Both objects I'm querying (langDTs and langInstructionsAVDTs) are Entity Framework (.Net 3.5) objects from the same database. My Where Clause (== av.InstructionAVKey) uses a simple Value Collection Class, nothing to see there.
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();
Any ideas on how I could see the LINQ translation of this Join? ::- ). I noticed that System.Data.Objects has more types of queries, but I can't get any of the ones which seem more relevant to this case, to work.
LATER EDIT:
As you recommended, I tried changing the IEnumerable to an IQueryable but that resulted in a type incompatibility compilation error ::- /.
After doing an explicit cast, I got the same error, but at Runtime (Unable to cast object of type '<DistinctIterator>d__7a1[EGSLanguageProviderShared.DTODataType]' to type 'System.Linq.IQueryable
1[EGSLanguageProviderShared.DTODataType]'.`)
Additional code: my objects langDTs and langInstructionsAVDTs are:
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());
So these objects are indeed queried immediately because they are Lists ::- ). As for DTODataType and DTOInstructionActiveValueDataType, they are simple Value Collection Classes, just public Properties, that's all.
EVEN LATER EDIT
Might be of interest that at their root, the objects I'm using are indeed declared as ObjectQuery back in the deepest layer (Entity Framework):
public global::System.Data.Objects.ObjectQuery<instructions> instructions
However, as I bring the data from over the Data Access Layer, I am converting them to Data Transfer Objects (the DTO-prefixed classes you keep seeing), which are simple Value Collection Classes (a property-by-property map of the Entity Objects which I use in order to keep the Data Model completely separated from the View and also to execute any data post-processing in the Presentation side).
Instead of typing your variable as IEnumerable<DTODataType>
try IQueryable<DTODataType>
, or even var.
I'm guessing somewhere in there your query is getting executed, and the results being stored as IEnumerable
, and therefore no longer able to be cast as ObjectQuery
EDIT
Can you please expand your code snippet to show were both langDTs and langInstructionsAVDTs come from?
Based on your subsequent edit, it's clear that you are simply querying and joining in memory collections. That's why you can't cast to ObjectQuery
, and that's also why you can't declare the query to be of type IQueryable<T>
.
In other words there's no way to do a dump of the SQL being issued, because no SQL is being issued. Once you converted your data over to your in-memory collection of DTOs, you became disconnected from your database, and all your queries became linq-to-objects queries with no corresponding T-SQL being generated.
精彩评论