DaniloTec 0 Denunciar post Postado Junho 16, 2009 Boa tarde gente. Estou executando um SqlDataReader dentro de um RowDataBound e está exibindo o seguinte erro: There is already an open DataReader associated with this Command which must be closed first.Será que é porque ele executa o SqlDataReader em cada linha? if (e.Row.RowType == DataControlRowType.DataRow){ string strDepartamento = ""; SqlCommand sqlDepartamentos = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + e.Row.Cells[4].Text + ")", conn); SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); while(drDepartamentos.Read()){ strDepartamento += drDepartamentos["txt_departamento"].ToString(); } drDepartamentos.Close(); drDepartamentos.Dispose(); sqlDepartamentos.Dispose(); }Mas como vcs podem ver, eu estou fechando o dr.Existe outra forma de executer uma query dentro do RowDataBound? Compartilhar este post Link para o post Compartilhar em outros sites
quintelab 91 Denunciar post Postado Junho 16, 2009 Este erro ocorre em qual das linhas? Abraços... Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 16, 2009 SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); Compartilhar este post Link para o post Compartilhar em outros sites
quintelab 91 Denunciar post Postado Junho 16, 2009 Você não deu um Open na sua conexão. De uma olhada neste exemplo: http://msdn.microsoft.com/en-us/library/sy...der(VS.71).aspx Abraços... Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 17, 2009 Então, Quintelab. Eu já tinha tentado isso e tmb não deu certo. Ele alega que já existe uma conexão aberta. protected void gvCandidatos_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { string strDepartamento = ""; conn.Open(); SqlCommand sqlDepartamentos = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + e.Row.Cells[4].Text + ")", conn); SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); while(drDepartamentos.Read()){ strDepartamento += drDepartamentos["txt_departamento"].ToString(); } drDepartamentos.Close(); drDepartamentos.Dispose(); sqlDepartamentos.Dispose(); conn.Close(); } } The connection was not closed. The connection's current state is open.Mas como você pode ver, não há nenhuma conexão aberta.Outra coisa, pq essas páginas da msdn não tem barra de rolagem? rs Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 17, 2009 Acho que descobri porque ele exibe o erro, só não sei o que fazer para resolver. Tenho o seguinte codigo que popula o grid: try { conn.Open(); SqlCommand sqlBusca = new SqlCommand(strBusca, conn); SqlDataReader drBusca = sqlBusca.ExecuteReader(); gvCandidatos.DataSource = drBusca; gvCandidatos.DataBind(); drBusca.Close(); drBusca.Dispose(); sqlBusca.Dispose(); conn.Close(); }catch(System.Data.SqlClient.SqlException ex){ Response.Write(ex.Message); }E o código dentro do RowData: protected void gvCandidatos_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { string strDepartamento = ""; conn.Open(); SqlCommand sqlDepartamentos = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + e.Row.Cells[4].Text + ")", conn); SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); while(drDepartamentos.Read()){ strDepartamento += drDepartamentos["txt_departamento"].ToString(); } drDepartamentos.Close(); drDepartamentos.Dispose(); sqlDepartamentos.Dispose(); conn.Close(); } }Pelo que notei, ele não permite que se crie dois SqlDataReader simultâneos com a mesma conexão.É isso mesmo? Como eu resolvo isso? Compartilhar este post Link para o post Compartilhar em outros sites
quintelab 91 Denunciar post Postado Junho 17, 2009 É isso mesmo, deve utilizar a mesma conexão sem fechar ela ou utilizar outra conexão. Abraços... Compartilhar este post Link para o post Compartilhar em outros sites
pedro.wtf 0 Denunciar post Postado Junho 17, 2009 Você está fechando o drDepartamentos, mas e o DataReader que você usa para carregar o 'e', este já está fechado? Boa tarde gente. Estou executando um SqlDataReader dentro de um RowDataBound e está exibindo o seguinte erro: There is already an open DataReader associated with this Command which must be closed first.Será que é porque ele executa o SqlDataReader em cada linha? if (e.Row.RowType == DataControlRowType.DataRow){ string strDepartamento = ""; SqlCommand sqlDepartamentos = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + e.Row.Cells[4].Text + ")", conn); SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); while(drDepartamentos.Read()){ strDepartamento += drDepartamentos["txt_departamento"].ToString(); } drDepartamentos.Close(); drDepartamentos.Dispose(); sqlDepartamentos.Dispose(); }Mas como vcs podem ver, eu estou fechando o dr.Existe outra forma de executer uma query dentro do RowDataBound? Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 17, 2009 Sim! Segue o código que popula o grid: try { conn.Open(); SqlCommand sqlBusca = new SqlCommand(strBusca, conn); SqlDataReader drBusca = sqlBusca.ExecuteReader(); gvCandidatos.DataSource = drBusca; gvCandidatos.DataBind(); drBusca.Close(); drBusca.Dispose(); sqlBusca.Dispose(); conn.Close(); }catch(System.Data.SqlClient.SqlException ex){ Response.Write(ex.Message); } Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 18, 2009 Opa!!! Descobri um jeito! Hehehe... Ao invés de utilizar o SqlDataReader para popular o GridView eu utilizei um DataSet. Ficou assim: Popular o grid: conn.Open(); DataSet dsBusca = new DataSet(); SqlDataAdapter daBusca = new SqlDataAdapter(strBusca, conn); daBusca.Fill(dsBusca, "Avaliacao"); gvCandidatos.DataSource = dsBusca.Tables["Avaliacao"]; gvCandidatos.DataBind(); daBusca.Dispose(); dsBusca.Dispose(); conn.Close(); Subquery da coluna: //BUSCA OS DEPARTAMENTOS string strDepartamento = ""; SqlCommand sqlDepartamentos = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + e.Row.Cells[5].Text + ")", conn); SqlDataReader drDepartamentos = sqlDepartamentos.ExecuteReader(); while(drDepartamentos.Read()){ strDepartamento += drDepartamentos["txt_departamento"].ToString() + "<br />"; } e.Row.Cells[5].Text = strDepartamento.ToString(); drDepartamentos.Close(); drDepartamentos.Dispose(); sqlDepartamentos.Dispose();Não é permitido utilizar 2 ou mais SqlDataReader abertos ao mesmo tempo, pra isso se utiliza um DataSet que pode armazenar várias tabelas que poder ser acessadas por Table[indice].Vlw!!! http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Compartilhar este post Link para o post Compartilhar em outros sites
Oenning 0 Denunciar post Postado Junho 18, 2009 Fuja dos DataSet :( Sobre seu problema, é isso que vocês comentaram mesmo, a variável conn está sendo usada para popular a grid e dentro do RowDataBound. Como o DataReader trabalha conectado, quando você popula sua grid para cada linha ele vai executando o RowDataBoud que por sua vez vai fazer uma query no banco, mas a conn ainda está sendo usada para popular a Grid. Confusão :P Você precisa usar duas instâncias diferentes desta variável. O que eu faria: No RowDataBound, faça algo assim: if (e.Row.RowType == DataControlRowType.DataRow){ string strDepartamento = departamentosService.GetAll(e.Row.Cells[4].Text); } Ou seja, crie uma classe para fazer essa query, fica mais organizado, é reutilizavel, é mais fácil dar manutenção depois etc... Dentro do método GetAll, você abre uma nova conexão e faz o que deve ser feito =) Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 18, 2009 Porque fugir do DataSet? :blink: Tentei fazer o que você disse, mas acho que não segui o caminho correto. Suponha que o método que eu criei retorna a string que eu preciso: public string retornaDepartamento(string ids) { return ""; }Depois crio o objeto e chamo o método: Comum objComum = new Comum(); string strDepartamento = objComum.retornaDepartamento(e.Row.Cells[4].Text);É isso mesmo? Onde aparece o GetAll? Compartilhar este post Link para o post Compartilhar em outros sites
Juliano.net 2 Denunciar post Postado Junho 19, 2009 Danilo, DataSets são armazenadores de dados off-line, ou seja, copiam todo o conteúdo retornado pelo Command para a memória, no entanto, trabalhar com DataSets em Grid é muito mais fácil pois permite que você utilize o DataView para ordenar e filtrar registros, o que trará mais produtividade e talvez até mais performance (considerando a ordenação e filtro em runtime). Compartilhar este post Link para o post Compartilhar em outros sites
Oenning 0 Denunciar post Postado Junho 19, 2009 É GetAll foi um exemplo, no seu caso está certo como você fez. Mas o projeto sendo web, acho que não vai ter essas vantagens, a menos que ele guarde o dataset no ViewState. Compartilhar este post Link para o post Compartilhar em outros sites
DaniloTec 0 Denunciar post Postado Junho 22, 2009 O método que retorna o resultado ficou desta forma: try { conn.Open(); string strDepartamento = ""; SqlCommand sqlDepartamento = new SqlCommand("select txt_departamento from tbl_departamentos where id_departamentos in (" + ids + ")", conn); SqlDataReader drDepartamento = sqlDepartamento.ExecuteReader(); if (!drDepartamento.HasRows){ return "Não consta"; }else { //drDepartamento.Read(); while (drDepartamento.Read()) { strDepartamento += drDepartamento["txt_departamento"] + "<br />"; } return strDepartamento; } conn.Close(); sqlDepartamento.Dispose(); drDepartamento.Close(); drDepartamento.Dispose(); }catch(System.Data.SqlClient.SqlException ex){ return ex.Message; }Ficou certinho, mas se tiver uma forma de melhorar, sou todo ouvidos, hehehe...Vlw gente! Compartilhar este post Link para o post Compartilhar em outros sites