SqDataReader在.net中关闭了问题

时间:2012-08-21 19:05:01

标签: asp.net sqldatareader executereader

我已经创建了一个执行查询并返回SqlDataReader的函数,现在我在另一个函数中使用它与返回的数据一起工作,但是我得到错误,说读者已经关闭了。这是功能:

public static SqlDataReader ExecuteReader(string procedure, SqlParameter[] parameters, CommandType commandType)
    {
        SqlDataReader reader = null;
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            using (SqlCommand command = new SqlCommand(procedure, connection))
            {
                connection.Open();
                if(parameters != null)
                {
                    if (commandType == CommandType.StoredProcedure)
                        command.Parameters.AddRange(parameters);
                }
                reader = command.ExecuteReader();
            }
        }
        return reader;
    }

这是我调用SqlDataReader

的代码
using (SqlDataReader reader = SqlHelper.ExecuteReader("select top 10 username from users", null, System.Data.CommandType.Text))
        {
            Response.Write(reader.IsClosed); //This returns True

        }

4 个答案:

答案 0 :(得分:2)

修改

ExecuteReader with CommanBehavior ( automatically close connection after reading data)

过度连接关闭问题只需使用CommandBheviour

- CommandBehavior.CloseConnection 
   When you pass above values as argument to ExecuteReader 
     1. there is no need to close connection explicitly connection get close when you close your reader. 

代码将是这样的,无需明确关闭连接

public void CreateMySqlDataReader(string mySelectQuery,string myConnectionString) 
{
   SqlConnection myConnection = new SqlConnection(myConnectionString);
   SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
   myConnection.Open();
   SqlDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
   while(myReader.Read()) 
   {
      Console.WriteLine(myReader.GetString(0));
   }
   myReader.Close();
   //Implicitly closes the connection because CommandBehavior.CloseConnection was specified.
}

因为您正在关闭连接而导致问题

SqlReader始终使用开放式连接,即使用此链接时打开的实时连接

using (SqlConnection connection = new SqlConnection(connectionString)) 
        {
}

它配置读取器对象使用的连接对象,为什么它的隐藏IsColosed为真

如果你想要返回值objec而不是使用DataTable这是断开连接的数据对象和doens makse使用连接

修改后的代码

  public static DataTable ExecuteReader(string procedure, SqlParameter[] parameters, CommandType commandType)
  {
     DataTable dt = null;
     using (SqlConnection connection = new SqlConnection(connectionString))
     {
         using (SqlCommand command = new SqlCommand(procedure, connection))
         {
              connection.Open();
              if(parameters != null)
              {
            if (commandType == CommandType.StoredProcedure)
            command.Parameters.AddRange(parameters);
              }
                SqlDataAdapter da = new SqlDataAdapter(command);
                da.Fill(dt);
           }
         }
            return dt;
        }

答案 1 :(得分:1)

DataReader需要一个Open Connection。您可以做什么返回DataTable或使用自定义类来表示SQL查询的结果并返回该实例。

创建一个代表您的实体的类

public class Customer
{
  public int ID { set;get;}
  public string Name { set;get;}
}

在你的方法中;

public List<Customer> GetCustomer()
{
  List<Customer> custList=new List<Customer>();
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
    using (SqlCommand command = new SqlCommand("yourParameterizedSQLQuery", 
                                                                  connection))
    {
     //Add parameters if needed
     connection.Open();

    using (var reader = cmd.ExecuteReader())
    {
       if (reader.HasRows)
       {
           cust=new Customer();
           while(reader.Read())
           {
             var cust=new Customer();
             // TO DO :Do db null checking before reading 
             cust.ID=reader.GetInt32(reader.GetOrdinal("ID"));
             cust.Name=reader.GetString(reader.GetOrdinal("Name"));
             custList.Add(cust);
           }
       }
     }
    }
  }  
 return custList;   
 }   

答案 2 :(得分:0)

问题是您有using SqlConnection在离开作用域时关闭与数据库的连接。

SqlDataReader需要“仍然开放”的连接。将其返回到父级不会保持连接打开。

您的选择基本上是返回DataSet,这是一个“未连接”的数据源,或者更改管理连接以打开它的方式,使用SqlDataReader,关闭连接。

答案 3 :(得分:0)

您可能必须打开连接并让调用代码关闭与阅读器关联的连接。

我遇到了这个挑战,所以我将回复类型更改为DataTable

reader = command.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
return dt;

这样我就不必担心在该方法之外关闭连接