如果您在提到的链接上有scrolled down,您就会遇到IDbCommandInterceptor 界面。它的功能更加丰富,它可以判断查询是成功执行还是失败。
一个示例实现可能是:
public class LogDbCommandInterceptor : IDbCommandInterceptor
{
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
interceptionContext.SetUserState("start", DateTime.Now);
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
Console.WriteLine($"parameters: {FormatParams(command.Parameters)}, exception: {interceptionContext.Exception?.Message}");
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
interceptionContext.SetUserState("start", DateTime.Now);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
interceptionContext.SetUserState("start", DateTime.Now);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
}
private static double CalculateDuration<T>(DbCommandInterceptionContext<T> context)
{
return (DateTime.Now - (DateTime)context.FindUserState("start")).TotalMilliseconds;
}
private static bool HasFailed<T>(DbCommandInterceptionContext<T> context)
{
return context.OriginalException != null || (context.IsAsync && context.TaskStatus != TaskStatus.RanToCompletion);
}
private static string FormatParams(ICollection dbParameterCollection)
{
if (dbParameterCollection.Count == 0)
return string.Empty;
var parameterDescriptor = new StringBuilder();
foreach (SqlParameter parameter in dbParameterCollection)
{
parameterDescriptor.AppendFormat("{0} {1}: {2}, ", parameter.DbType, parameter.ParameterName, parameter.Value);
}
return parameterDescriptor.ToString().TrimEnd(' ', ',');
}
}
Console.WriteLine 当然可以用您自己的记录器替换。
如您所见,您可以使用OriginalException 属性读取异常。其他感兴趣的属性被监听here.
还可以在here 找到注册实施的简短指南:
注册拦截器
一旦创建了实现一个或多个拦截接口的类,就可以使用 DbInterception 类向 EF 注册它
拦截器也可以使用基于 DbConfiguration 代码的配置在应用域级别注册
您还可以使用 app.config 文件配置拦截器