【问题标题】:EntityFramework LINQToEntities generate weird slow TSQL Where-Clause实体框架 LINQ To 实体生成奇怪的慢 SQL Where-Clause
【发布时间】:2014-04-09 14:05:03
【问题描述】:

我需要明白这一点。 EF5.0和EF6.*在TSQL代码生成上有很大区别

在我的代码中,这是我的 LINQ - 声明

var qry2 = context.viw_overview_1.Where(i => i.article_EAN17 == ean).Select(i => i.article_id).Take(200);

EntityFramework 5.0 只生成一个简单快速的 TSQL WHERE - 像这样的语句,非常完美

... WHERE [Extent1].[article_EAN17] = @p__linq__0
00.0960096ms in SSMS

但是 EntityFramework 6.* 生成一个非常复杂和缓慢的语句

... WHERE (([Extent1].[article_EAN17] = @p__linq__0) AND ( NOT ([Extent1].[article_EAN17] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[article_EAN17] IS NULL) AND (@p__linq__0 IS NULL))
45.3665362ms in SSMS

字段 article_EAN17 也有一个索引。 但是 EF6.* 无论如何都需要很长时间才能初始化,但是 有没有办法 在 EF6.* 中生成一个简单的 WHERE 语句,其中包含属性或类似的东西? 我试过 string.Equals()string.Compare() ,交换参数,但没有任何改变。

Why does Entity Framework 6 generate complex SQL queries for simple lookups?解释区别,但是有没有办法强制EF生成简单的TSQL。

【问题讨论】:

  • 我怀疑 T-SQL 的变化正在减慢速度。您是否在同一个数据集上尝试了这两个查询?
  • 只是好奇 - 你有没有将这两个语句打入 SSMS 并比较它们的性能?
  • EF5 的简单比较在 C# 中比 EF6 快 5 倍,在 SSMS 中快得多
  • EF 的部分优点在于您不必关心这些事情,或者只关心一点点 - 否则泄漏的抽象会沉没。除了一些高级方法来控制发生的情况,例如使用 .Include 或 .AsNoTracking 如果您的性能要求要求使用确切的 SQL,然后考虑使用存储过程。
  • 不包括在这个范围内吗? entityframework.codeplex.com/workitem/145

标签: c# sql linq entity-framework


【解决方案1】:

我相信这与您在实体框架中的 NULL 比较设置有关

在您的查询前添加以下代码,看看它是否有助于您的查询性能:

context.ContextOptions.UseCSharpNullComparisonBehavior = true;

【讨论】:

【解决方案2】:

如果您绝对肯定需要取消添加的空检查,您可以随时使用DbSet.SqlQuery()(文档here)手动配置您希望运行的查询(以及所有参数)。不过要小心,因为有时该方法可能会以您意想不到的方式起作用。如果您不想/不需要任何跟踪,您也可以使用Database.SqlQuery<T>()(文档here),这将允许您在查询中使用泛型(否则您将不得不强制转换它)。

我个人更愿意不管它,或者使用存储过程,比如 cmets 中提到的@EricScherrer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2011-01-15
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多