问题
I'm analyzing the queries that are running in a DB (Azure Sql Server V12) and I found a few queries generated by Entity Framework (EF 6.0) that make no sense to me. They are really bad for performance and I cannot find where they are generated.
(@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]
Solution: if you have a query like this it means you have EF 6.0 or older and you are doing a simple dbContext.SellerPhones.Any(p => xxx). Just upgrade to 6.1 and the generated query will be much better.
回答1:
To find out where the query is generated, enable the EF Logging (either to the console or your logging framework.) Once you have that turned on, try to find part of the query (like [dbo].[SellerPhone] AS [Extent2]) in your logs, and with the other logs surrounding the query, you should know where you are.
This should help you enable the logging:
public MyContext : DbContext
{
private static ILog log = LogManager.GetCurrentClassLogger();
public MyContext(string connectionString)
: base(connectionString)
{
this.Database.Log = (msg) => log.Trace(msg);
}
}
回答2:
I did what Tipx described but I also added the stack trace to be able to know which method was generating each query:
Database.Log = (sql =>
{
System.Diagnostics.Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
System.Diagnostics.Debug.WriteLine(sql);
});
In EF 6.0, a simple query like dbContext.SellerPhones.Any(p => condition) will generate an ugly query that has a CASE and calls the EXISTS twice.
After upgrading to EF 6.1 the query has only ONE EXISTS and performs much better (I highlighted below that part of the generated query that was updated).
SELECT CASE WHEN ( EXISTS (SELECT 1 AS [C1] FROM [dbo].[SellerPhone] AS [Extent1] WHERE [Extent1].[Phone] = @p__linq__0 )) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
来源:https://stackoverflow.com/questions/43684008/entity-framework-generated-really-bad-sql-when-using-any