![](/img/trans.png)
[英]ServiceStack OrmLite - Capture Sql InfoMessage event from stored procedure
[英]SqlCommand.ExecuteReaderAsync stops firing InfoMessage event after first SELECT statement in a stored procedure
我必須使用存儲過程來訪問數據,並使用從數據庫引擎發送的消息(如PRINT 'hello'
)。
當我使用SQL連接的InfoMessage
事件並將數據填充到DataTable
,一切都很完美。
但是,當我必須按順序讀取數據並使用SqlDataReader.ExecuteReaderAsync
,連接會在存儲過程中的第一個select語句之后停止觸發InfoMessage:
C#代碼:
using (SqlConnection con = new SqlConnection("connection-string"))
{
con.Open();
con.InfoMessage += (s, e) => {
Console.WriteLine(e.Message);
};
using (SqlCommand command = new SqlCommand("spTestMessage", con))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader reader = await command.ExecuteReaderAsync();
int cntr = 0;
while (reader.Read())
{
Console.WriteLine($"Loaded row {cntr++}");
}
// reader.NextResult(); // this line forces firing rest of InfoMessage events
}
}
SQL存儲過程:
CREATE PROCEDURE [dbo].[spTestMessage]
AS
PRINT 'Before select 1'
select * from MyTable
PRINT 'After select 1'
PRINT 'Before select 2'
select * from MyTable
PRINT 'After select 2'
節目輸出:
Before select 1
為什么它停止工作? 我認為Reader有問題,因為當我使用command.ExecuteNonQueryAsync();
而不是command.ExecuteReaderAsync();
,它也有效。
我偶然發現,那個評論的行reader.NextResult();
強制連接刷新消息並觸發剩余事件。 然而,這是一個非常不吉利的解決方法。
謝謝你的幫助!
你的command.ExecuteNonQueryAsync()
在第一次運行后停止給出你的結果,有或沒有reader.ReadAsync()
,因為任何async SQL命令將在第一個結果返回給客戶端時完成,並且info messages
算得上了。 當你觸發reader.NextResult() or await reader.NextResultAsync()
它會與讀者聯系以獲得更多結果。
如果您想了解有關Asynchronous
SQL處理的更多信息,可以查看Remus的答案,對於NextResult
請查看此示例 。
使用InfoMessages
:
var _msgs = new List<string>();
using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(<YourConnectionString>))
{
//Appending an event handler for InfoMessages
con.InfoMessage += delegate (object sender, SqlInfoMessageEventArgs args)
{
//reader will invoke the delegate on every itteration of results coming from query
_msgs.Add(args.Message);
return;
};
using (var cmd = new System.Data.SqlClient.SqlCommand("spTestMessage", con))
{
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
using (System.Data.SqlClient.SqlDataReader reader = await cmd.ExecuteReaderAsync())
{
var incr = 0;
while (await reader.ReadAsync())
{
//Statements to read data from Table1
Console.WriteLine(reader.GetString(0));
incr++;
}
while (await reader.NextResultAsync())
{
while (await reader.ReadAsync())
{
//Statements to read data from Table2
Console.WriteLine(reader.GetString(0));
incr++;
}
}
}
}
}
注意:上述過程可以與Synchronous
操作一起使用,只需將方法的簽名從異步更改為同步即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.