如何在EF Select命令中记录记录数

时间:2016-09-08 06:46:56

标签: entity-framework entity-framework-6

我使用EF通过SELECT语句获取记录。对于某些性能问题,我需要记录命令,以便返回的行数例如1000.但我找不到任何示例或文档来执行此操作。

我认为可以使用IDbCommandInterceptor并实现CommandExecuted方法来实现。但不确定。

IDbCommandInterceptor是可用的还是应该以另一种方式进行?

2 个答案:

答案 0 :(得分:0)

您可以使用Context Log property,如下所示。

注意:这只是一个例子。根据需要更改它。

 using (var context = new BlogContext()) 
   { 
    context.Database.Log = Console.Write; 

    var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 
  }

以上将生成以下输出:

SELECT TOP (1)
    [Extent1].[Id] AS [Id],
    [Extent1].[Title] AS [Title]
    FROM [dbo].[Blogs] AS [Extent1]
    WHERE (N'One Unicorn' = [Extent1].[Title]) AND ([Extent1].[Title] IS NOT NULL)
-- Executing at 10/8/2013 10:55:41 AM -07:00
-- Completed in 4 ms with result: SqlDataReader

如果需要,您可以自定义DatabaseLogFormatter

您可以覆盖以下提到的方法:

  

LogCommand - 覆盖它以更改以前记录命令的方式   他们被处决了。默认情况下,LogCommand为每个调用LogParameter   参数;您可以选择在覆盖或句柄中执行相同操作   参数不同而不是。

     

LogResult - 覆盖它以改变执行结果的方式   命令已记录。

     

LogParameter - 覆盖它以更改格式和内容   参数记录。

以下是如何执行此操作的示例:

public class OneLineFormatter : DatabaseLogFormatter 
{ 
    public OneLineFormatter(DbContext context, Action<string> writeAction) 
        : base(context, writeAction) 
    { 
    } 

    public override void LogCommand<TResult>( 
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext) 
    { 
        Write(string.Format( 
            "Context '{0}' is executing command '{1}'{2}", 
            Context.GetType().Name, 
            command.CommandText.Replace(Environment.NewLine, ""), 
            Environment.NewLine)); 
    } 

    public override void LogResult<TResult>( 
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext) 
    { 
    } 
}

参考: Logging and Intercepting Database Operations

答案 1 :(得分:0)

搜索网络和调试&amp;跟踪&amp;调查EF Source我意识到当前的实施不可能做到这一点。 IDbCommandInterceptor.CommandExecuted Interceptor刚刚在Database上查询后调用,只有我们有DbDataReader,command,...但是没有获取记录计数。 获取对DbDataReader的获取记录计数枚举应该可以获得行计数。所以我改变了EF LazyEnumerator,在每次调用MoveNext之后,增加局部变量,在处理LazyEnumerator时,我们获取了行号或物化实体号