Cancelar insert em banco de dados

Olá amigos, gostaria de saber como faço para cancelar a inclusão de dados que são acrescentados a um DataAdapter no Visual Studio utilizando C#.

Já tentei utilizar os métodos MeuDataAdapter.Update(MeuDataSet) e MeuDataAdapter.AcceptChanges() no botão de Salvar e MeuDataAdapter.RejectChanges() no botão de Cancelar mas percebi que os dados se tornam persistentes no banco de dados logo no método MeuTableAdapter.Insert(parametro1,parametro2) que é o primeiro comando do botão Inserir.

O que posso estar esquecendo ou fazendo errado?

Você pode postar seu código?

O código é muito simples porque estou utilizando o modo design do Visual Studio:

private void btIncluiProd_Click(object sender, EventArgs e)
    {
        int id_orcam, id_produto, quantidade;
        id_orcam = int.Parse(lblNumero.Text);//Obtém o valor da chave primária de Orçamentos
        id_produto = Convert.ToInt32(cboxProduto.SelectedValue); // Obtém o valor da chave primária de produtos
        quantidade = Convert.ToInt32(cboxQuant.SelectedItem); // Informa a quantidade de itens de um produto
        decimal preco_item = Convert.ToDecimal(int.Parse(tbPrecoProposta.Text)); //Obtém o preço corrente alterado ou não            

        itemTableAdapter.Insert(id_orcam, id_produto, quantidade, preco_item);
       //itemTableAdapter.Update(vorc2DataSet.Item); // Este trecho adicionei no botão de Inserir
        //vorc2DataSet.AcceptChanges(); // Este trecho adicionei no botão de inserir
        itemTableAdapter.Fill(vorc2DataSet.Item);
        dgvpProd.DataSource = produtoTableAdapter.GetDataByIDOrc(id_orcam); //Preenche com a consulta
    }

Adicionei um botão para cancelar a inserção com este método vorc2DataSet.rejectChanges(); que não funcionou.

Vanderlei,

Creio o problema é de lógica.

Pense que para gravar ou cancelar, existe uma determinada condição (que depende de sua regra de negócio), portanto, gravar ou cancelar, depende dessa condição ser atendida.
Uma vez que você chamou a rotina ‘IncluiProd’ (que está no evento click do botão) ela será realizada e é isso que deve acontecer.
Sendo assim, só chame a rotina salvar se você tem certeza que quer salvar a informação.

Não está claro o que faz o botão cancelar. Se você quer apenas descartar os dados de um form, basta apenas sair ou limpar os componentes (Text, OptionButton, etc), sem fazer qualquer persistência no BD.

Dica:Separe a coisas, evite codificar nos eventos. Crie métodos à parte, assim você pode reutlilizá-lo em outras situações. Você pode reutilizar por exemplo em outro botão click, form1, form2, menu, menuitem, menucontext, etc., chamando o mesmo método. Senão, você teria que reescrever o código salvar em todos eles, ou usar outras formas (delegates) para chamar o método que está no evento do botão.

Vou demonstrar através de um pseudo código: (Informo que não conheço a regra de negócio, portanto, é só um modelo)

private void btIncluiProd_Click(object sender, EventArgs e)
{
	if condiçãoAtendida então
		if(GravarDados(param1, param2, ...))     //o método retorna um bool, se retornar verdadeiro atualiza gridview
			AtualizarGridView();
		else
			TratarErro();
		fim if
	fim if
}

Public bool GravarDados(param1, param2, ...)  
{
	try {
		codificação....
		return true      //se sucesso, retorna verdadeiro
	}
	catch {
		return false    //senão, retorna falso
	}
	
}

public void AtualizarGridView()
{
   codificação....
}

Percebi que você tem um datagridview (dgvpProd).
Esse dgv deve ser atualizando quando? Somente se o dado for inserido no banco, ou em qualquer circunstância?
Encontre uma solução para separar a atualização do gridview e a persistência no BD, mesmo que ambos sejam atualizados simultaneamente.

1 curtida

Obrigado Roberto pelas ótimas dicas. Andei observando o meu código e percebi que vou ter que refazê-lo. Incluí tudo no click para facilitar a visualização no fórum intencionalmente para não ter que escrever trechos de código separadamente e deixar muito grande a explicação. Um detalhe importante é que eu cadastro Clientes e Produtos normalmente direto no banco sem precisar de um dataset temporário, mas não achei solução de como ligar o CLIENTE e PRODUTOS a um Orçamento sem precisar acrescentá-los no banco para obter as chaves primárias que são geradas automaticamente no momento do Insert. Pela lógica eu teria que fazer um Insert “cancelável”. Foi isso que imaginei que deveria acontecer quando comecei a fazer o programa, mas percebi que não é bem assim.

Bem… observando tudo aqui depois de um tempo sem mexer no código, percebi que terei de achar uma solução para armazenar os dados de forma temporária no Datagridview, utilizando apenas consulta ao banco, obtendo a chave atual e incrementá-la no momento da inserção ou descartar os dados no caso do botão “cancelar”.
Para finalizar e deixar claro o que parece ser o meu maior erro: quando adiciono um produto a um cliente, tenho feito isto acrescentando ao BD e retornando a consulta para Datagrid, onde na verdade deveria ser ao contrário, acrescentar ao Datagrid e só então enviar para o BD.

Fico grato pela sua ajuda. Vou tentar refazer a lógica e melhorar no meu aprendizado.

Wanderlei, Agora entendi.

O seu “insert cancelável” é um DELETE, e isso está correto.
Para você poder fazer o orçamento OBRIGATORIAMENTE ambos os “atores” (clientes e produtos) devem existir, portanto tem que estar no banco.
Nesse caso, você não cancela o cliente e/ou produtos, você cancela (deleta) o orçamento.
Quanto a deletar o cliente, se não houver orçamento, dependente (novamente) da regra de negócio, mas isso é bem incomum.
Pense num e-commerce, quando você vai ao site, obrigatoriamente faz um cadastro (nome, endereço, cpf, etc.) É aqui que ocorre o INSERT do cliente, O produto necessariamente deve estar pré-cadastrado. Só depois, é que você pode/consegue comprar. Se você não comprar nada (cancelar a compra) , o seu carrinho fica vazio, mas o seu cadastro continua lá.
Sendo assim, você SEMPRE conseguirá “ligar” cliente e produto, porque ambos já estão no banco…
Se o seu gridview é a exibição do orçamento, então você o atualizará quando o ORÇAMENTO for gravado no banco. Se o orçamento for cancelado, ou você DELETA, ou usa um campo de status, sinalizando que o orçamento e/ou itens foram cancelados. A questão do status é porque tem empresas que medem (indicadores estatísticos) as compras não realizadas, portanto, elas não deletam o orçamento. Veja que o que falei aqui não ficou muito diferente do pseudo código que escrevi. Onde, GravarDados() seria gravar o orçamento. Faltou apenas o método cancelar que no meu exemplo, seria remover itens ou esvaziar o carrinho (orçamento). Lembrando que nas operações de CRUD você sempre irá atualizar o gridview, para exibir corretamente os itens do orçamento.

Acredito que agora o assunto se encerra. Um abraço! Boa sorte!