![](/img/trans.png)
[英]SqlCommand.ExecuteReaderAsync stops firing InfoMessage event after first SELECT statement in a stored procedure
[英]ServiceStack OrmLite - Capture Sql InfoMessage event from stored procedure
几天前问过这个问题,但也许并不太具体。
基本上,我正在编写一个控制台应用程序,它接受存储过程名称列表并随意执行它们。 应用程序应该记录Slack等关于这些sprocs的进展,以及稍后做一些其他的事情。
我提到的“其他东西”与已知的数据库模型交互,因为我们有一个ServiceStack / OrmLite类型库,所以我以后使用OrmLite与数据库进行交互。
因此,由于我在项目中包含并配置了OrmLite,我只是使用OrmLite IDbConnection
来执行存储过程,即使它只是名称。 sprocs只是将数据移动到另一个数据库,一个应用程序不需要与之交互的数据库 - 因此我不会使用sprocs将任何数据SELECT
到应用程序中,并且没有POCO表示移动的内容。
然而,sprocs吐出了许多我想捕获的信息PRINT
语句,并通过Slack以格式化方式登录我们的团队。 启用完整的调试日志记录会为此目的提供一些过多的信息。
有没有什么方法可以配置Ormlite
SqlServerDialect.Provider
, IDataReader
等基本上捕获SqlConnection.InfoMessage
事件(或者为它提供已经准备好SqlInfoMessageEventHandler
的连接)?
执行此操作的日志记录策略方法是在日志记录提供程序中配置过滤器,以仅记录您感兴趣的消息。
包含SQL和DB参数的OrmLite的SQL调试日志消息记录在ServiceStack.OrmLite.OrmLiteResultsFilterExtensions
类型下。
为了OrmLiteConfig.BeforeExecFilter
这个场景,我刚刚添加了新的OrmLiteConfig.BeforeExecFilter
和OrmLiteConfig.AfterExecFilter
,您可以在执行DB命令之前和之后执行自定义逻辑,例如:
OrmLiteConfig.BeforeExecFilter = dbCmd => Console.WriteLine(dbCmd.GetDebugString());
此更改可从v5.0.3获得,现在可在MyGet上使用 。
通过ServiceStack.OrmLite来源看,它看起来像IDbConnection
可以转换为SqlConnection
使用(SqlConnection)IDbConnection.ToDbConnetion()
将其包装在OrmLiteExecFilter
以在每个语句上调用,转换IDbConnection
并使用强制转换连接创建DbCommand
对我OrmLiteExecFilter
:
public class LogInfoMessageFilter : OrmLiteExecFilter { ILog SlackLog = LogManager.GetLogger("SlackLogger"); public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter) { var holdProvider = OrmLiteConfig.DialectProvider; // casting, skipping type checks for brevity var sqlConn = (SqlConnection)dbConn.ToDbConnection(); // add the event sqlConn.InfoMessage += _HandleInfoMessage; var dbCmd = CreateCommand(sqlConn); try { return filter(dbCmd); } finally { DisposeCommand(dbCmd, sqlConn); OrmLiteConfig.DialectProvider = holdProvider; } } private void _HandleInfoMessage(object sender, SqlInfoMessageEventArgs args) { SlackLog.Info($"what does the sproc say? {args.Message}"); } } // before opening the connection: OrmLiteConfig.ExecFilter = new LogInfoMessageFilter();
但是,现在@mythz用“官方”方式回复了这个问题,我将继续进行重构。 我以为我会把它放在这里,以防它适合任何人的用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.