如果在SqlDataReader关闭之前我们无法检索输出参数,那么为什么......?

时间:2010-04-13 19:34:57

标签: .net asp.net ado.net sqldatareader sqlconnection

1)

  

在使用SqlDataReader时,关联的SqlConnection正忙于为SqlDataReader提供服务,除了关闭SqlConnection之外,不能对SqlConnection执行任何其他操作。在调用SqlDataReader的Close方法之前就是这种情况。例如,在调用Close之前,无法检索输出参数。

如果上述说法属实,那么为什么以下方法能够在读取器关闭之前从输出参数中检索值:

    public int Something()
    {
        using (SqlConnection con = new SqlConnection(this.ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("some_procedure", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@ID", SqlDbType.Int).Direction = ParameterDirection.Output;
            con.Open();
            cmd.ExecuteReader();
            return (int)cmd.Parameters["@ID"].Value;
        }
    }

2)

  

您可以重置CommandText属性并重用SqlCommand对象。但是,必须先关闭SqlDataReader,然后才能执行新命令或上一个命令。

为什么在执行新命令之前必须关闭sqldatareader?

感谢名单

2 个答案:

答案 0 :(得分:3)

在第一个问题中,您正在执行NonQuery - 因此在获取输出参数之前没有要关闭的阅读器。

对于第二个问题,你就是这样做的。当一个阅读器打开时,该命令不会让你打电话给另一个阅读器。

答案 1 :(得分:0)

请原谅我直接陈述,但你似乎没有清楚地了解数据阅读器(System.Data.IDataReader)到底是什么。所以,让我演示一下:

using System;
using System.Data;
using System.Data.SqlClient;

string connectionString = "...";

// create and open a DB connection:
using (IDbConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    // create a command object:
    using (IDbCommand query = connection.CreateCommand())
    {
        query.CommandType = CommandType.Text;
        query.CommandText = "SELECT ID, Name, Birthdate FROM SomeTable";

        // execute the query and retrieve a data reader object:
        using (IDataReader reader = query.ExecuteReader())
        {
            // the data reader is now used to read the query result:
            while (reader.Read())
            {
                int id = reader.GetInt32(0);
                string name = reader.GetString(1);
                DateTime birthdate = reader.GetDateTime(0);
            }
        }

        // at this point, the data reader object has been disposed.
        // the DB connection can now be used again, e.g. by issuing
        // another query:

        command.CommandText = "SELECT COUNT(*) FROM SomeOtherTable";
        ...
    }
}

注意:我已经避免使用var,因此您可以确切了解所涉及的类型。 (还要注意,我使用的主要是IDbConnection等接口类型,而不是SqlConnection等具体实现类。这使得代码更容易适应其他RDBMS。)

您现在可以看到,在您的代码中,您从未真正使用过数据读取器。因此,您的代码工作正常,因为从来没有一个开放的数据读取器可以首先“阻止”您的数据库连接。