Заставить платформу сущностей загрузить связанный конец, используя ExecuteStoreQuery / esql

У меня есть отношение 1-1 в моей базе данных, и когда я использую .Include() EF генерирует ужасный запрос, который исполняется годами (mutliple joins). Поэтому я подумал - я напишу свой собственный запрос для загрузки этих объектов. Что я пробовал:

  • Я пытался использовать ExecuteStoreQuery, но это была пустая трата времени, поскольку он не может реализовать сложные свойства
  • Я пытался использовать объектный запрос с ESQL, но даже если я добавляю соединение, связанное свойство не загружается. И (очевидно), если я добавлю .Include() тогда EF генерирует тот же ужасный запрос.

Итак, вопрос в том, существует ли способ материализации сущностей в обход запросов SQL, которые генерирует EF?..

ОБНОВЛЕНИЕ: просто пример запроса EF.

Код:

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

И это приводит к следующему SQL (я отредактировал запрос, чтобы сделать его более читабельным):

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'

1 ответ

Решение

Есть ли способ материализации сущностей в обход запросов SQL, которые генерирует EF?

В большинстве случаев нет, потому что:

  • ExceuteStoreQuery не может загрузить отношения
  • ESQL не может загрузить отношения без использования Include

Фактические варианты:

  • Используйте два отдельных запроса - один для главных объектов и один для зависимых объектов (вы можете построить правильный where пункт из основных юридических лиц). Если у вас все настроено правильно и вы отключили ленивую загрузку, EF автоматически исправит связь при загрузке связанных сущностей.
  • Используйте.NET 4.5 и сопоставьте рукописную SQL / хранимую процедуру, возвращающую два набора результатов - один для основных объектов и один для связанных объектов. Это требует ручной модификации (и ручного обслуживания) файла EDMX.
Другие вопросы по тегам