Usuário com melhor resposta
Fazer Update DataSet

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?
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"]
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"]
-
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? -
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:
-
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? -
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:
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