By Marcio Valerio Silva - 1/19/2011
Eu preciso adicionar algumas restrições de integridade para impedir que sejam deletados registros que sejam chaves estrangeiras em outras tabelas. Até aí tudo bem no Deployment Database do SF é moleza!
Mas como capturar as excessões causadas por essa excessão e tratá-las mostrando uma mensagem mais amigavel ao usuário Final, sem que apareceça aquela tela do SF de tarja vermelha que parece que o "mundo vai acabar".
Não achei uma maneira até agora.
|
By Ivan George Borges - 1/20/2011
Dê uma olhada no seu AppMain.vb/Program.cs na Sub UnhandledExceptionFound.
Lá você pode por exemplo setar e.Handled = True e manipular a excessão como desejar.
|
By Marcio Valerio Silva - 4/21/2011
Olá Ivan Ainda estou com uma dificuldade.
Dentro do Form onde é que eu consigo pegar a string da excessão. Eu já tentei de diversas formas e até agora eu não consegui.
Alguns clientes não aceitam muito bem a mensagem em ingles do banco de dados e eu realmente preciso fazer algo mais simplificado ao diaer ao cliente que é uma questão de integridade referencial e não um erro comum.
Hoje aparece assim a mensagem:
SqlException The DELETE statement conflicted with the REFERENCE constraint "NovosTitulos". The conflict occurred in database "m2enterprise", table "dbo.RenegociacaoNovosTitulos", column 'CtaReceberId'. The statement has been terminated.
E eu gostaria simplesmente de mostrar a mensagem dizendo que trata-se de uma informação constante na tabela "xxxx" do banco de dados
Se você puder me passar o meio eu agradeço muito!
Um bom feriado e até mais.
At,
Marcio Valerio da Silva
|
By Marcio Valerio Silva - 4/24/2011
Olá Ivan!
Olha o melhor que eu consegui até agora foi o seguinte:
Criei um código no BO assim:
public string DeleteRegistroIR(int _id) { string _retorno = string.Empty; StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.AppendFormat("Delete {0} where clientesId = {1}", this.TableName, _id.ToString()); using (SqlCommand cmd = new SqlCommand()) { cmd.CommandText = sqlBuilder.ToString(); try { this.ExecuteNonQuery(cmd); } catch (SqlException ex) { _retorno = ex.Message; } } return _retorno; }
E adicioneu no evento BeforeDelete para parar a execução da deleção do form conforme abaixo:
private void frmClientes_BeforeDelete(MicroFour.StrataFrame.Business.BeforeDeleteEventArgs e) { e.Cancel = true; string _mensagem = clientesBO1.DeleteRegistroIR(clientesBO1.ClientesId); if (!string.IsNullOrEmpty(_mensagem)) { MessageBox.Show("Exclusão não Permitida! \n Há Informações Vinculadas em Outros Registros!", "", MessageBoxButtons.OK, MessageBoxIcon.Stop); } } }
Desta forma quando o BO me retorna alguma mensagem informo o usuário que o registro não será excluido, pois existe informação em outra tabela relacionada.
Outro problema é que desta forma eu não consegui separar a tabela que gerou o conflito afim de informar o usuário, para que mesmo assim ele queira excluir o registro ele possa excluir as informações de tabelas referenciadas e depoi concluir a exclusão.
No código acima eu não gostei que após a confimação de deleção mesmo se o usuário não confirmar a deleção é excutado o evento BeforeDelete eu acredito que não deveria pois não foi confirmado a deleção pelo usuário.
Por favor me passe a forma correta de executar este procedimento.
|
By Ivan George Borges - 4/25/2011
Olá Márcio.
Primeiro, se você estiver procurando lidar com a mensagem de excessão, como eu te disse, deveria dar uma olhada no UnhandledExceptionFound no seu Program.cs. Neste ponto, você pode capturar a mensagem e lidar com ela como quiser. Eu, por exemplo, monto um form onde coloco a mensagem que foi capturada e um diálogo com o usuário tentando traduzir o que aconteceu. Além disto, mando automaticamente esta mensagem para nosso email de suporte, com identificação do erro e quando e onde ocorreu. Se der uma olhada no Help, vai encontrar explicação sobre isto em Application Framework -> Application -> WinForms -> Appmain.vb (program.cs) File -> UnhandledExceptionFound().
Quanto a lidar com a situação de não permitir uma exclusão caso o registro corrente já tenha sido utilizado como uma ForeignKey em outra tabela, o ideal seria que criasse um BusinessObject Base para sua aplicação e colocasse o código para lidar com isto no BeforeDelete do mesmo. Depois, deveria criar todos os seus BO herdando deste seu BaseBO.
Nos seus forms, caso não queira que a mensagem de Exclusão apareça automaticamente, deveria configurá-los com AutoShowDeleteConfirmation = False. E mais uma vez, se espera ter isto como padrão em todos os seus forms, deveria criar um Form Base, configurar as propriedades que queira neste form e depois fazer com que todos os forms de sua aplicação herdem de seu BaseForm.
No seu BaseBO, no BeforeDelete, a propriedade This.TableName te dirá em qual tabela o usuário está tentando excluir e a partir daí você pode testar nas outras tabelas onde este registro pode ter sido utilizado se existe a ForeignKey da tabela corrente, e em caso positivo, informar ao usuário inclusive onde foi usado.
Então, se não foi usado, você mostra uma mensagem de confirmação de Exclusão, já que a automática foi desligada, e pega a resposta do cliente confirmando a Exclusão.
No fim, se encontrou o registro usado em outra tabela ou se o usuário não confirmou a exclusão, você faz "e.Cancel = True", isto cancelará a exclusão.
O BeforeDelete sempre será executado e é nele que você vai testar se o Delete realmente deve ser obedecido.
|
By Marcio Valerio Silva - 4/25/2011
Ola Ivan,
Muito Obrigado por enquanto, gostei da informação de envio da mensagem para o e-mail. Vou adotar algo parecido aqui.
Desculpe incomodar, mas foi necessário nesse momento.
Até mais.
|
By Ivan George Borges - 4/25/2011
Que é isto! De nada, não é incômodo nenhum.
Vai postando que a gente vai tentando ajudar. Uma dica, se conseguir postar em Inglês, mesmo que seja usando aqueles tradutores do Google, a sua pergunta poderá ser lida por todo mundo. Às vezes eu não estou aqui no momento e então outra pessoa pode tentar te ajudar também. Mas se não se sentir à vontade para isto, pode ir colocando em Português que sempre que dá eu entro e tento responder.
Abração.
|
|