测量每个实体框架查询的时间

Hug*_*une 5 c# sql-server performance entity-framework entity-framework-6

为了测量和调试 Entity Framework 6.3 中每个查询的时间,我DbCommandInterceptor根据相关问题的接受答案实现了一个 :

public class EFLogger : IDbCommandInterceptor
{
    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        startMeasuring(command, interceptionContext);
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        stopMeasuring(command, interceptionContext);
    }
    ...
}

DbInterception.Add(new EFLogger());
Run Code Online (Sandbox Code Playgroud)

这工作正常,在每个命令发送到数据库之前和之后调用它,我可以测量它所花费的时间。

但是,它仅测量初始化之前的时间SqlDataReader。每个查询的大部分时间都是在SqlDataReader迭代和消耗时花费的。我想知道每个查询需要多长时间,最好不要为每个语句添加秒表代码。

SqlDataReader当关闭或读取“最终”记录时,我可以以某种方式拦截吗?

我意识到这些SqlDataReader可能并不总是被完全消耗掉,因此最终的记录可能很难检测到。目前,我只对迭代SqlDataReader到最后的情况感兴趣。

该接口似乎IDbCommandInterceptor没有为此提供任何事件。

是否有其他机制可以捕获阅读器关闭时的瞬间?

或者我可以将自定义DbDataReader包装器注入实体框架代码中吗?或者 SQL Server 端有其他方法吗?

Arj*_*ani 3

您可以将日志输出到控制台,context.Database.Log = Console.Write请参阅https://learn.microsoft.com/en-us/ef/ef6/fundamentals/logging-and-interception了解更多信息。

using (var context = new BlogContext())
{
    context.Database.Log = Console.Write; // set Database.Log property inside dbContex constructor to log all queries
    //your query here
}
Run Code Online (Sandbox Code Playgroud)

这将输出每个查询以及传递的参数和执行查询所需的时间。