none
Fazer Update DataSet RRS feed

  • Pergunta

  • olá pessoal, tenho um form em que para o mesmo arrastei uma datagridview e ao clicar na smart tag,
    de seguida na opção Choose Data Source fiz a ligação à bd sem escrever uma linha de código.

    Verifiquei que no evento load do form foi colocado o seguinte codigo:

    - >// TODO: This line of code loads data into the 'bDWSERVIDORDataSet.utilizadores' table. You can move, or remove it, as needed.
                this.utilizadoresTableAdapter.Fill(this.bDWSERVIDORDataSet.utilizadores);

    Entretanto coloquei um botao para salvar as alterações na grid e coloquei no evento Click o seguinte código:
    ->this.utilizadoresTableAdapter.Update(this.bDWSERVIDORDataSet.utilizadores);


    Tudo funciona muito bem.

    Entretanto decidi fazer o mesmo mas desta vez fazer a ligação à bd programaticamente e fiz o seguinte:

    conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=BDWSERVIDOR.mdb";
               
    conn.Open();

    str = "select * from utilizadores";
    command = new OleDbCommand(str, conn);
    da = new OleDbDataAdapter(command);
    ds=new DataSet ();

    da.Fill(ds, "utilizadores");           
    dataGridView_direita.DataSource = ds;
    dataGridView_direita.DataMember = "utilizadores";

    Com este codigo a grid é preenchida.De seguida adicionei um botao cuja função era salvar alterações nos registos e é aqui que começa o problema,
     tentei usar a seguinte instrução:
    ->this.da.Update(this.ds);
    como usei quando fiz a ligação à bd apenas com clicks do rato mas nao funciona como dá erro.

    também tentei fazer da seguinte maneira:
    ->this.da.Update(this.ds.Tables ["utilizadores"]);
    mas dá erro.

    verifiquei que ao clicar na tecla ponto a seguir à variavel ds(dataset) no intellisense não aparece a tabela utilizadores
    como aparece quando faço na variável dataset bDWSERVIDORDataSet
    na intrução "this.utilizadoresTableAdapter.Update(this.bDWSERVIDORDataSet.utilizadores);"
    em que neste caso me aparece a tabela utilizador quando a ligação à BD é feita apartir do botão Samrt Tag.

    Importa dizer qua a minha ideia inicial era fazer um select com join como por  exemplo:
    str = "select * from utilizadores, filas where utilizadores.ID_util=Filas.ID_util";

    mas como estava a ter problemas em fazer update numa tabela resolvi fazer apenas o select usandoa  a tabela utilizadores.


    será que alguém me pode dar uma ajuda?
    quinta-feira, 8 de janeiro de 2009 23:43

Respostas

  •  nett_fan wrote:
    olá pessoal, tenho um form em que para o mesmo arrastei uma datagridview e ao clicar na smart

    conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=BDWSERVIDOR.mdb";
               
    conn.Open();

    str = "select * from utilizadores";
    command = new OleDbCommand(str, conn);
    da = new OleDbDataAdapter(command);
    ds=new DataSet ();

    da.Fill(ds, "utilizadores");           
    dataGridView_direita.DataSource = ds;
    dataGridView_direita.DataMember = "utilizadores";

    Com este codigo a grid é preenchida.De seguida adicionei um botao cuja função era salvar alterações nos registos e é aqui que começa o problema,
     tentei usar a seguinte instrução:
    ->this.da.Update(this.ds);
    como usei quando fiz a ligação à bd apenas com clicks do rato mas nao funciona como dá erro.

    também tentei fazer da seguinte maneira:
    ->this.da.Update(this.ds.Tables ["utilizadores"]);
    mas dá erro.

     

     

    Sempre informe quais são as mensagens de erro.

     

    De qualquer forma, o que provavelmente está acontecendo é que os comandos de inserção, atualização etc., do banco não foram passados ao objeto DataAdapter. O DataAdapter contém propriedades como InsertCommand, UpdateCommand etc, para receber os respectivos comandos de atualização do banco, e você não está ajustando essas propriedades.

     

    Há no Framework uma classe chamada SqlCommandBuilder que gerará os comandos de inserção, atualização e remoção (para uma única tabela) para você a partir do comando de seleção desde que a tabela contenha uma chave primária. Há um exemplo (em VB) no tópico do link:

     

    http://forums.microsoft.com/msdn-br/ShowPost.aspx?PostID=2167718&SiteID=21

     nett_fan wrote:

    verifiquei que ao clicar na tecla ponto a seguir à variavel ds(dataset) no intellisense não aparece a tabela utilizadores
    como aparece quando faço na variável dataset bDWSERVIDORDataSet
    na intrução "this.utilizadoresTableAdapter.Update(this.bDWSERVIDORDataSet.utilizadores);"
    em que neste caso me aparece a tabela utilizador quando a ligação à BD é feita apartir do botão Samrt Tag.

     

     

    O que o designer gera é o chamado DataSet tipado, que na verdade é uma classe toda customizada derivada do DataSet e que contém outras classes customizadas aninhadas, como classes derivadas de DataTables e cujas instãncias são retornadas a partir de propriedades criadas no DataSet etc.; daí ser possível acessar o DataTable do modo como você descreveu acima.

     

    O que você está usando no segundo caso é o objeto DataSet genérico, que não contém aquelas propriedades da classe customizada gerada pelo designer. Para acessar o DataTable (também genérico) existente nesse DataSet, você deve passar o nome (ou o índice) do DataTable para a propriedade Tables:

     

    SeuDataSet.Tables["SeuDataTable"]

     

     

     

    sexta-feira, 9 de janeiro de 2009 10:49

Todas as Respostas

  •  nett_fan wrote:
    olá pessoal, tenho um form em que para o mesmo arrastei uma datagridview e ao clicar na smart

    conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=BDWSERVIDOR.mdb";
               
    conn.Open();

    str = "select * from utilizadores";
    command = new OleDbCommand(str, conn);
    da = new OleDbDataAdapter(command);
    ds=new DataSet ();

    da.Fill(ds, "utilizadores");           
    dataGridView_direita.DataSource = ds;
    dataGridView_direita.DataMember = "utilizadores";

    Com este codigo a grid é preenchida.De seguida adicionei um botao cuja função era salvar alterações nos registos e é aqui que começa o problema,
     tentei usar a seguinte instrução:
    ->this.da.Update(this.ds);
    como usei quando fiz a ligação à bd apenas com clicks do rato mas nao funciona como dá erro.

    também tentei fazer da seguinte maneira:
    ->this.da.Update(this.ds.Tables ["utilizadores"]);
    mas dá erro.

     

     

    Sempre informe quais são as mensagens de erro.

     

    De qualquer forma, o que provavelmente está acontecendo é que os comandos de inserção, atualização etc., do banco não foram passados ao objeto DataAdapter. O DataAdapter contém propriedades como InsertCommand, UpdateCommand etc, para receber os respectivos comandos de atualização do banco, e você não está ajustando essas propriedades.

     

    Há no Framework uma classe chamada SqlCommandBuilder que gerará os comandos de inserção, atualização e remoção (para uma única tabela) para você a partir do comando de seleção desde que a tabela contenha uma chave primária. Há um exemplo (em VB) no tópico do link:

     

    http://forums.microsoft.com/msdn-br/ShowPost.aspx?PostID=2167718&SiteID=21

     nett_fan wrote:

    verifiquei que ao clicar na tecla ponto a seguir à variavel ds(dataset) no intellisense não aparece a tabela utilizadores
    como aparece quando faço na variável dataset bDWSERVIDORDataSet
    na intrução "this.utilizadoresTableAdapter.Update(this.bDWSERVIDORDataSet.utilizadores);"
    em que neste caso me aparece a tabela utilizador quando a ligação à BD é feita apartir do botão Samrt Tag.

     

     

    O que o designer gera é o chamado DataSet tipado, que na verdade é uma classe toda customizada derivada do DataSet e que contém outras classes customizadas aninhadas, como classes derivadas de DataTables e cujas instãncias são retornadas a partir de propriedades criadas no DataSet etc.; daí ser possível acessar o DataTable do modo como você descreveu acima.

     

    O que você está usando no segundo caso é o objeto DataSet genérico, que não contém aquelas propriedades da classe customizada gerada pelo designer. Para acessar o DataTable (também genérico) existente nesse DataSet, você deve passar o nome (ou o índice) do DataTable para a propriedade Tables:

     

    SeuDataSet.Tables["SeuDataTable"]

     

     

     

    sexta-feira, 9 de janeiro de 2009 10:49
  • olá Angus, desde já obrigado pela atenção. Relativamente ao erro gerado, a msg que aparece quando clico no botão para salvar alterações na grid é a seguinte:->{"Update requires a valid UpdateCommand when passed DataRow collection with modified rows."}, esta msg aparece ao executar a instrução, this.da.Update(this.ds.Tables ["utilizadores"]); .

    Após adicionar a instrução  OleDbCommandBuilder cmbuilder= new OleDbCommandBuilder(dtaadap), já funciona .
    Já agora aproveito para falar no caso em que faço um select com join como por exemplo:
    str = "select * from utilizadores, filas where utilizadores.ID_util=Filas.ID_util".

     Que alterações implica este join em todo o processo?vi mum post que me indicou que quando o select é a varias tabelas tenho que
    montar os comandos INSERT, UPDATE e DELETE no DataAdapter manualmente.será que não me pode indicar nenhum exemplo sff?
    sexta-feira, 9 de janeiro de 2009 17:42
  •  nett_fan wrote:
    olá Angus, desde já obrigado pela atenção. Relativamente ao erro gerado, a msg que aparece quando clico no botão para salvar alterações na grid é a seguinte:->{"Update requires a valid UpdateCommand when passed DataRow collection with modified rows."}, esta msg aparece ao executar a instrução, this.da.Update(this.ds.Tables ["utilizadores"]); .

    Após adicionar a instrução  OleDbCommandBuilder cmbuilder= new OleDbCommandBuilder(dtaadap), já funciona .
    Já agora aproveito para falar no caso em que faço um select com join como por exemplo:
    str = "select * from utilizadores, filas where utilizadores.ID_util=Filas.ID_util".

     Que alterações implica este join em todo o processo?vi mum post que me indicou que quando o select é a varias tabelas tenho que
    montar os comandos INSERT, UPDATE e DELETE no DataAdapter manualmente.será que não me pode indicar nenhum exemplo sff?

     

    Ao invés de utilizar a classe CommandBuilder para montar automaticamente os comandos no DataAdapter, você os monta munualmente e os atribui às propriedades relevantes do DataAdapter, exatamente como você fez acima para o comando SELECT. Aquela sobrecarga do construtor do objeto DataAdapter para a qual você passou o objeto Command inicializa a propriedade SelectCommand do DataAdaper com o dito objeto Command; seria a mesma coisa instanciar o DataAdapter com o construtor padrão (sem parâmetros) e ajustar em seguida a propriedade SelectCommand do objeto . É simples, mas um pouco trabalhoso.

     

    No site da Microsoft há exemplos:

     

    SelectCommand

    InsertCommand

    UpdateCommand

    DeleteCommand

    sexta-feira, 9 de janeiro de 2009 18:45
  • olá Angus, que confusão, para começar, mas eu preciso de usar o SelectCommand para carregar a Grid?não posso fazer assim:
                   
    str = "select * from utilizadores, filas where utilizadores.ID_util=Filas.ID_util";

                    command =new OleDbCommand (str,conn);

                    dtaadap = new OleDbDataAdapter(command );             
                   
                    ds=new DataSet ();           

                    dtaadap.Fill(ds, "utilizadores");
                    dtaadap.Fill(ds, "filas");
                  
                    dataGridView_direita.DataSource = ds;
                    dataGridView_direita.DataMember = "utilizadores";

    Se bem que neste caso eu tive que optar por uma das tabelas para o DataMember, não sei se está correcto. depois nos exemplos é sempre feito um SelectCommand, não percebi porque, também não sei se tenho que usar 2 OleDbDataAdapter, porque nos exemplos o select é feito a apenas uma tabela. Não conhece um exemplo mais esclarecedor?
    sexta-feira, 9 de janeiro de 2009 22:31
  •  nett_fan wrote:
    olá Angus, que confusão, para começar, mas eu preciso de usar o SelectCommand para carregar a Grid?não posso fazer assim:
                   
    str = "select * from utilizadores, filas where utilizadores.ID_util=Filas.ID_util";

                    command =new OleDbCommand (str,conn);

                    dtaadap = new OleDbDataAdapter(command );             
                   
                    ds=new DataSet ();           

                    dtaadap.Fill(ds, "utilizadores");
                    dtaadap.Fill(ds, "filas");
                  
                    dataGridView_direita.DataSource = ds;
                    dataGridView_direita.DataMember = "utilizadores";

     

     

    Mas esse É o SelectCommand. Você está apenas se utilizando de um "atalho", por assim dizer, usando o construtor da classe OleDbDataAdapter para criar o SelectCommand. Eu expliquei isso na minha mensagem anterior:

     

    Aquela sobrecarga do construtor do objeto DataAdapter para a qual você passou o objeto Command inicializa a propriedade SelectCommand do DataAdaper com o dito objeto Command; seria a mesma coisa instanciar o DataAdapter com o construtor padrão (sem parâmetros) e ajustar em seguida a propriedade SelectCommand do objeto.

     

     

     nett_fan wrote:


    Se bem que neste caso eu tive que optar por uma das tabelas para o DataMember, não sei se está correcto. depois nos exemplos é sempre feito um SelectCommand, não percebi porque, também não sei se tenho que usar 2 OleDbDataAdapter, porque nos exemplos o select é feito a apenas uma tabela. Não conhece um exemplo mais esclarecedor?

     

    O DataGridView só pode exibir uma única tabela num dado momento e, portanto, só pode ter um DataMember. Mas você pode manter várias tablelas (objetos DataTable) num objeto DataSet.

     

    Quanto a mais exemplos, dê uma olhada no site do Macoratti. Por exemplo:

     

    http://www.macoratti.net/vbn_dat1.htm

    http://www.macoratti.net/vbn_xls2.htm

     

     

     

     

    sexta-feira, 9 de janeiro de 2009 23:34