【问题标题】:Query in Entity Framework takes longer than direct sqlEntity Framework 中的查询比直接 sql 需要更长的时间
【发布时间】:2015-06-16 17:54:47
【问题描述】:

主要问题是当我在 SQL Management Studio 中执行某个查询时,大约需要 2 秒。当通过实体框架执行时,我用探查器查看它,查询需要 260 秒。结果只有 72 行 1 个整数。此查询是根据用户定义的过滤器构建的。

有没有人有什么建议可能是错的? 我在 profiler 中可以看到的 sqlquery 如下:

SELECT [Distinct1].[PersonID] AS [PersonID]
FROM   (SELECT DISTINCT [Extent1].[PersonID] AS [PersonID]
         FROM   (SELECT [PersonViewWithExtraInfo].[PersonID]           AS         [PersonID],
                   [PersonViewWithExtraInfo].[DateTime]             AS [DateTime],
                   [PersonViewWithExtraInfo].[ExtraInfo1]         AS [ExtraInfo1],
                   [PersonViewWithExtraInfo].[ExtraInfo2]           AS [ExtraInfo2],
                   [PersonViewWithExtraInfo].[ExtraInfo3]               AS [ExtraInfo3],
                   [PersonViewWithExtraInfo].[ExtraInfo4] AS [ExtraInfo4]
            FROM   [core].[PersonViewWithExtraInfo].AS [PersonViewWithExtraInfo].AS [Extent1]
           LEFT OUTER JOIN [core].[Persons] AS [Extent2]
             ON [Extent1].[PersonID] = [Extent2].[PersonID]
    WHERE  ([Extent1].[ExtraInfo4] = 1)
           AND(([Extent2].[FirstName] = 'Steven' /* @p__linq__0 */)
                 OR (([Extent2].[FirstName] IS NULL)
                     AND ('Steven' /* @p__linq__0 */ IS NULL))
                 OR ([Extent2].[FirstName] = 'Steffi' /* @p__linq__1 */)
                 OR (([Extent2].[FirstName] IS NULL)
                     AND ('Steffi' /* @p__linq__1 */ IS NULL))
                 OR ([Extent2].[FirstName] = 'Evy' /* @p__linq__2 */)
                 OR (([Extent2].[FirstName] IS NULL)
                     AND ('Evy' /* @p__linq__2 */ IS NULL)))
           AND ([Extent1].[DateTime] >= '2014-06-01T00:00:00' /* @p__linq__3 */)
           AND ([Extent1].[DateTime] <= '2015-05-31T00:00:00' /* @p__linq__4 */)) AS [Distinct1]

我构建了 where 子句来比较这样的字符串:

public static Expression<Func<string, bool>> ConvertToExpression(this FilterComparer comparer, string compareValue)
  {
     switch (comparer)
     {
        case FilterComparer.IsEqualTo:
           return x => x == compareValue;
...

编辑:我发现问题出在哪里。当我从 sqlprofiler 获取查询时,查询被 exec sp_executesql 包围,当我将其粘贴到管理工作室时,查询所用的时间与使用 EF 一样长。因此,当我删除此查询中的空检查时,延迟就消失了。当他说“每个 where 子句有太多表达式”时,我应该听 EF 分析器。唯一的事情是实体框架添加了空检查。我怎样才能防止这种情况发生?

编辑:这是我从 Linq Insight 获得的 linq-query。

(from x in     ((ObjectQuery<PersonViewWithExtraInfo>)PersonViewWithExtraInfo).MergeAs(0)
where x.ExtraInfo4 && (((False || (True && (x.Person.FirstName     == compareValue))) || (True && (x.Person.FirstName == compareValue))) || (True     && (x.Person.FirstName == compareValue)))
where (x.DateTime >= startDate.Date) && (x.DateTime <= endDate.Date)
select x.PersonID).Distinct()

之所以有真假,是因为查询是根据用户定义的过滤器动态构建的。

【问题讨论】:

  • 那么如果您将确切的查询粘贴到 SSMS 中需要 2 秒?
  • 是的,然后需要 2 秒
  • 那么现在查询中剩下的所有空检查都由 EF 添加?
  • 是的,我只在 where 子句中添加 x == compareValue。如果我的 compareValue 为 null,我可以签入代码,然后将适当的表达式添加到 where 子句。
  • 开发机器上还是服务器上的管理工作室?

标签: c# sql-server entity-framework-6


【解决方案1】:

所以问题在于 EF 向查询添加了空检查,这使得 where 子句变得很大。 通过设置

Configuration.UseDatabaseNullSemantics = true;

在 DbContext 上问题已解决!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多