![](/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.