我正在分析在数据库(Azure Sql Server V12)中运行的查询,我发现实体框架(EF 6.0)生成的一些查询对我来说毫无意义。它们对性能非常不利,我找不到它们的生成位置。
(@p__linq__0 nvarchar(4000))SELECT
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[SellerPhone] AS [Extent1]
WHERE [Extent1].[Phone] = @p__linq__0
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[SellerPhone] AS [Extent2]
WHERE [Extent2].[Phone] = @p__linq__0
)) THEN cast(0 as bit) END AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
解决方案:如果你有这样的查询,这意味着你有EF 6.0或更早版本,而你正在做一个简单的dbContext.SellerPhones.Any(p => xxx)。只需升级到6.1,生成的查询就会好得多。
答案 0 :(得分:1)
要查找生成查询的位置,请启用EF日志记录(控制台或日志记录框架。)启用后,尝试查找部分查询(如[dbo].[SellerPhone] AS [Extent2]
)您的日志以及查询周围的其他日志,您应该知道自己的位置。
这可以帮助您启用日志记录:
public MyContext : DbContext
{
private static ILog log = LogManager.GetCurrentClassLogger();
public MyContext(string connectionString)
: base(connectionString)
{
this.Database.Log = (msg) => log.Trace(msg);
}
}
答案 1 :(得分:0)
我做了Tipx描述的内容,但我还添加了堆栈跟踪,以便能够知道生成每个查询的方法:
Database.Log = (sql =>
{
System.Diagnostics.Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
System.Diagnostics.Debug.WriteLine(sql);
});
在EF 6.0中,像dbContext.SellerPhones.Any(p => condition)之类的简单查询将生成一个丑陋的查询,该查询具有CASE并调用两次EXISTS。
升级到EF 6.1后,查询只有一个EXESTS并且执行得更好(我在下面突出显示了已更新的生成查询的部分)。
选择 情况(存在(选择 1 AS [C1] FROM [dbo]。[SellerPhone] AS [Extent1] 在哪里[Extent1]。[电话] = @ p__linq__0 ))然后施放(1比特)ELSE 施放(0比特)结束AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable1]