0

我的数据库中有一个 1-1 关系,当我使用.Include()EF 时会生成一个可怕的查询,该查询需要很长时间才能执行(多重连接)。所以我想 - 我会编写自己的查询来加载这些实体。我尝试了什么:

  • 我尝试使用 ExecuteStoreQuery,但这是浪费时间,因为它无法实现复杂的属性
  • 我尝试使用带有 ESQL 的对象查询,但即使我在那里添加连接,也不会加载相关属性。并且(显然)如果我添加一个.Include()then EF 会生成同样可怕的查询。

所以,问题是 - 有没有办法绕过 EF 生成的 SQL 查询来实现实体?

更新:只是 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'
4

1 回答 1

1

有没有办法绕过 EF 生成的 SQL 查询来实现实体?

在大多数情况下没有,因为:

  • ExceuteStoreQuery无法加载关系
  • ESQL 无法加载关系而不使用Include

实际的选项是:

  • 使用两个单独的查询 - 一个用于主体实体,一个用于依赖实体(您可以where从主体实体构造正确的子句)。如果您已正确配置所有内容并关闭延迟加载 EF 将在加载相关实体时自动修复关系
  • 使用 .NET 4.5 并映射手写 SQL/存储过程,返回两个结果集 - 一个用于主体实体,一个用于相关实体。这需要手动修改(和手动维护)EDMX 文件。
于 2012-08-17T06:53:18.400 回答