2013-11-14 2 views
2

У меня вопрос об использовании, почему я не могу использовать один и тот же экземпляр SQLCommand более одного раза в одном коде?, используя один и тот же экземпляр SQLCommand более одного раза в одном и том же коде для нескольких запросов?

Я попробовал код здесь, и она работает хорошо для GridView, но когда я изменил запрос, используя cmd.CommandText() метод, который он продолжает говорить:

Существует уже открытая DataReader, связанные с этой командой, которая должна быть первый закрыт.

Это код:

string cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString; 
SqlConnection con = new SqlConnection(cs); 

try 
{ 
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = con; 
    con.Open(); 
    cmd.CommandText = "Select top 10 FirstName, LastName, Address, City, State from Customers"; 

    GridView1.DataSource = cmd.ExecuteReader(); 
    GridView1.DataBind(); 


    cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers"; 
    int total = (int)cmd.ExecuteScalar(); 
    TotalCreditLble.Text = "The total Credit :" + total.ToString(); 

} 
catch(Exception exp) 
{ 
    Response.Write(exp.Message); 
} 
finally 
{ 
    con.Close(); 
} 

ответ

5

Проблема заключается в том, что вы используете SqlCommand объект для создания DataReader с помощью команды command.ExecuteReader(). Хотя это открыто, вы не можете повторно использовать команду.

Это должно работать:

using (var reader = cmd.ExecuteReader()) 
{ 
    GridView1.DataSource = reader; 
    GridView1.DataBind(); 
} 
//now the DataReader is closed/disposed and can re-use command 
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers"; 
int total = (int)cmd.ExecuteScalar(); 
TotalCreditLble.Text = "The total Credit :" + total.ToString(); 
4

Существует уже открытая DataReader, связанные с этой командой, которая должна быть закрыта первым.

Именно по этой причине вы не разделяете команду. Где-то в вашем коде вы сделали это:

cmd.ExecuteReader(); 

но не рычаги using заявления вокруг команды, потому что вы хотите поделиться. Вы не можете этого сделать. См., ExecuteReader оставляет соединение с сервером открытым, пока вы читаете одну строку за раз; однако эта команда заблокирована сейчас, потому что в данный момент она является работоспособной. Правильный подход, всегда, это:

using (SqlConnection c = new SqlConnection(cString)) 
{ 
    using (SqlCommand cmd = new SqlCommand(sql, c)) 
    { 
     // inside of here you can use ExecuteReader 
     using (SqlDataReader rdr = cmd.ExecuteReader()) 
     { 
      // use the reader 
     } 
    } 
} 

Это неуправляемые ресурсы и должны быть обработаны с осторожностью. Вот почему необходимо обернуть их с помощью using.

Не разделяйте эти объекты. Постройте их, откройте их, используйте и утилизируйте.

При использовании using вы будете не должны беспокоиться о получении этих объектов закрытыми и расположенными.


Ваш код, написанный немного по-другому:

var cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString; 
var gridSql = "Select top 10 FirstName, LastName, Address, City, State from Customers"; 
var cntSql = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers"; 

using (SqlConnection con = new SqlConnection(cs)) 
{ 
    con.Open(); 

    try 
    { 
     using (SqlCommand cmd = new SqlCommand(gridSql, con)) 
     { 
      GridView1.DataSource = cmd.ExecuteReader(); 
      GridView1.DataBind(); 
     } 

     using (SqlCommand cmd = new SqlCommand(cntSql, con)) 
     { 
      int total = (int)cmd.ExecuteScalar(); 
      TotalCreditLble.Text = "The total Credit :" + total.ToString(); 
     } 
    } 
    catch(Exception exp) 
    { 
     Response.Write(exp.Message); 
    } 
} 
+2

Я согласен с чувством о не повторно - использование команд/соединений, поскольку это может только вызвать у вас проблемы. –

0

Спасибо и quys, но и для ребят, где говорим об использовании блока! почему этот код работает отлично, что я видел его, например, на видео! Это то же самое, используя один и тот же экземпляр SqlCommand и передавая diffrent запросы с помощью метода CommanText с тем же экземпляром SqlCommand и это выполнить просто прекрасно, это код:

using (SqlConnection con = new SqlConnection(cs)) 
{ 
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = con; 
    con.Open(); 

    cmd.CommandText = "Delete from tbleProduct where ProductID= 4"; 
    int TotalRowsAffected = cmd.ExecuteNonQuery(); 
    Response.Write("Total rows affected :" + TotalRowsAffected); 

    cmd.CommandText = "Insert into tbleProduct values (4, 'Calculator', 100, 230)"; 
    TotalRowsAffected = cmd.ExecuteNonQuery(); 
    Response.Write("Total rows affected :" + TotalRowsAffected); 


    cmd.CommandText = "ypdate tbleProduct set QtyAvailbe = 234 where ProductID = 2"; 
    TotalRowsAffected = cmd.ExecuteNonQuery(); 
    Response.Write("Total rows affected :" + TotalRowsAffected); 

} 
Смежные вопросы