Question

I have a 1-1 relation in my database and when I use .Include() EF generates a horrible query that takes ages to execute (mutliple joins). So I thought - I will write my own query to load those entities. What I tried:

  • I tried using ExecuteStoreQuery, but that was a waste of time since it cannot materialize complex properties
  • I tried using an object query with ESQL, but even if I add a join there the related property is not loaded. And (obviously) if I add an .Include() then EF generates the same horrible query.

So, the question is - is there a way to materialize entities bypassing the SQL queries that EF generates?..

UPDATE: just an example of EF query.

The code:

var query = ctx.EntitySet
               .Include("RelatedProperty")
               .Where("it.SomeFilter=@param", new ObjectParameter(...));
var sql = query.ToTraceString();

And that produces the following SQL (I edited the query to make it more readable):

SELECT
    [Extent1].[SomeField] AS [SomeField],
    /* All remaining Extent1 fields */

    [Join1].[Id1] AS [Id1],
    /* All remaining Join1 fields */

    [Join3].[Id2] AS [Id2]
FROM   [OrderSet] AS [Extent1]
LEFT OUTER JOIN  (
    SELECT
        [Extent2].[SomeField] AS [SomeField],
        /* All remaining Extent2 fields */

        [Extent3].[SomeField] AS [SomeField],
        /* All remaining Extent3 fields */

    FROM  [CustomerSet] AS [Extent2]
    LEFT OUTER JOIN [OrderSet] AS [Extent3] 
        ON [Extent2].[Id] = [Extent3].[Customer_Id] ) AS [Join1] 
        ON [Extent1].[Customer_Id] = [Join1].[Id1]
LEFT OUTER JOIN  (
    SELECT 
        [Extent4].[SomeField] AS [SomeField],
        /* All remaining Extent2 fields */

        [Extent5].[SomeField] AS [SomeField],
        /* All remaining Extent3 fields */

    FROM  [CustomerSet] AS [Extent4]
    LEFT OUTER JOIN [OrderSet] AS [Extent5] 
        ON [Extent4].[Id] = [Extent5].[Customer_Id] ) AS [Join3] 
        ON [Extent1].[Customer_Id] = [Join3].[Id4]
WHERE [Extent1].[SomeFilter] = 'blah'
Was it helpful?

Solution

is there a way to materialize entities bypassing the SQL queries that EF generates?

In most cases no because:

  • ExceuteStoreQuery cannot load relatioins
  • ESQL cannot load relations without using Include

The actual options are:

  • Use two separate queries - one for principal entities and one for dependent entities (you can construct correct where clause from the principal entities). If you have everything correctly configured and you turned off lazy loading EF will fix relation automatically when loading related entities
  • Use .NET 4.5 and map hand written SQL / stored procedure returning two result sets - one for principal entities and one for related entities. This requires manual modification (and manual maintenance) of EDMX file.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top