C# ASP.NET-显示倍数的SqlConnection信息消息

C# ASP.NET-显示倍数的SqlConnection信息消息,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我正在从正在编写的web应用程序中单击运行SQL Server存储过程。存储过程可能会返回一些消息,该消息需要显示在应用程序中。但是,该消息正在打印多次 以下是我的代码片段: protected void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e) { lbxMessage.Items.Add(e.Message); } protected void btnTest_Cli

我正在从正在编写的web应用程序中单击运行SQL Server存储过程。存储过程可能会返回一些消息,该消息需要显示在应用程序中。但是,该消息正在打印多次

以下是我的代码片段:

    protected void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        lbxMessage.Items.Add(e.Message);
    }

    protected void btnTest_Click(object sender, EventArgs e)
    {
        lbxMessage.Items.Clear();

        String ConnString = "MyConnectionString"
        SqlConnection conn = new SqlConnection(ConnString);

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandTimeout = 300;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "uspTest";

        DataSet ds = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = cmd;

        conn.Open();
        conn.InfoMessage += new SqlInfoMessageEventHandler(conn_InfoMessage);
        cmd.ExecuteNonQuery();
        da.Fill(ds);
        conn.Close();
    }

在本例中,uspTest只是打印测试,但显示它的列表框显示TEST TEST

代码调用存储过程两次。一次调用da.Fillds填充数据集,一次调用ExecuteOnQuery

数据集未在问题代码中的任何位置使用,这意味着可以通过以下方式重写代码:

var cmd = new SqlCommand
{
    CommandText = "uspTest",
    CommandTimeout = 300,
    CommandType = CommandType.StoredProcedure
};
using (var conn = new SqlConnection(ConnString))
{
    conn.Open();                
    conn.InfoMessage += Conn_InfoMessage;


    cmd.Connection = conn;
    cmd.ExecuteNonQuery();                
}
using块确保即使发生异常,连接也将关闭

如果存储过程返回结果,则不应使用ExecuteOnQuery。代码应该如下所示:

var cmd = new SqlCommand
{
    CommandText = "uspTest",
    CommandTimeout = 300,
    CommandType = CommandType.StoredProcedure
};
var da = new SqlDataAdapter
{
    SelectCommand = cmd
};
using (var conn = new SqlConnection(ConnString))
{
    conn.Open();                
    conn.InfoMessage += Conn_InfoMessage;

    var ds = new DataSet();
    cmd.Connection = conn;
    da.Fill(ds);
    //Do something with the dataset
}

首先,为什么要使用InfoMessage?这是很少使用的。结果由存储过程作为结果集返回。打印邮件的内容不是结果。它们甚至不会立即发送到客户端-服务器会等到有足够的数据发送它们,以避免浪费带宽和引入延迟。您是否正在尝试在存储过程中实现进度报告?也许?@PanagiotisKanavos我正在使用InfoMessage返回信息性消息。我有返回sp的结果,代码我没有发布,因为它不相关。我正在运行的sp有一系列需要查看的打印语句。有关更多信息,我正在获取一系列以前通过SQL Server Management Studio逐个运行的存储过程,并将它们映射到按钮,以便我可以通过服务器上的应用程序运行它们。但是打印语句的内容是有价值的信息,所以不要使用打印语句。将信息写入日志/事件表。这实际上占用的空间更少,速度更快,因为您可以将事件定义存储在查找表中,并且只记录事件id和数据。您可以使用表变量并最终返回其内容。ETL作业和长时间运行的作业不使用打印