分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子
前言
EF 开发效率确实很高也很便捷,但当它发生错误时,也挺让人头疼的,为什么?因为 EF 就像是一个黑盒子,一切全被封装起来,出错的时候很难定位原因,如果能够知道并打印 EF 生成的 SQL 语句,对于定位 EF 错误,就很有帮助。
程序员的才智是无限的,虽然 EF 有这个那个的问题,但程序员却总比这些问题多一个办法。
下面分享一个 .NET 通过监听器拦截 EF 消息写日志的详细例子。
Step By Step 步骤
-
创建自定义监听器类,拦截 EF 的命令执行事件(留意注释)
/// /// 监听并写 EF 生成的 SQL 到日志 /// public class EFIntercepterLogging : IDbCommandInterceptor { /// /// 实现接口的 NonQueryExecuting 方法 /// /// /// public void NonQueryExecuting( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogWhenExecuting(command, interceptionContext); } /// /// 实现接口的 NonQueryExecuted 方法 /// /// /// public void NonQueryExecuted( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogIfError(command, interceptionContext); } /// /// 实现接口的 ReaderExecuting 方法 /// /// /// public void ReaderExecuting( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogWhenExecuting(command, interceptionContext); } /// /// 实现接口的 ReaderExecuted 方法 /// /// /// public void ReaderExecuted( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogIfError(command, interceptionContext); } /// /// 实现接口的 ScalarExecuting 方法 /// /// /// public void ScalarExecuting( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogWhenExecuting(command, interceptionContext); } /// /// 实现接口的 ScalarExecuted 方法 /// /// /// public void ScalarExecuted( DbCommand command, DbCommandInterceptionContext interceptionContext) { LogIfError(command, interceptionContext); } /// /// 写 EF 执行中的 SQL 日志,Debug 级别,用在 Executing 方法 /// /// /// /// private void LogWhenExecuting( DbCommand command, DbCommandInterceptionContext interceptionContext) { Logger.DebugFormat("Executing the following SQL: [{0}]", command.CommandText); } /// /// 出现异常时写日志到 Log4net /// /// /// /// private void LogIfError( DbCommand command, DbCommandInterceptionContext interceptionContext) { if (interceptionContext.Exception != null) { var errMsg = new StringBuilder(16); errMsg.AppendLine("Error occurred when executing the following SQL: "); errMsg.AppendLine(command.CommandText); foreach (DbParameter param in command.Parameters) { errMsg.AppendLine($"ParameterName:[{param.ParameterName}] -- DbType:[{param.DbType}] -- Value:[{param.Value}]"); } Logger.Error(errMsg, interceptionContext.Exception); } } } -
在 Global.asax 中的 Application_Start 方法注册监听器
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //autofac注册 AutofacConfig.RegisterConfig(); //注册 EF log 监听器 DbInterception.Add(new EFIntercepterLogging()); } -
这样就实现了监听器拦截 EF 消息写日志的功能,当运行程序执行 EF 语句时,就会自动将 EF 生成的 SQL 写到日志文件中
总结
通过实现自定义监听器类并注册监听器,可以跟踪和记录 EF 的操作和事件,在开发过程中更好地了解和调试 EF 的行为,不失为排查 EF 问题和优化 EF 性能的一个好方法。
我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

