|
Adrián De Armas
|
 |
« Respuesta #2 : 20 de Febrero de 2009, 16:47:00 » |
|
Hola,
El manejo de errores es, tal vez, una de las cosas mas flacas que tiene este ORM, habría que pensar como hacerlo mejor. Por ahora, el comportamiento que estas teniendo es exactamente el esperado. Cuando se guarda o elimina, en realidad cada vez que se hace alguna operación sobre la BD, las excepciones son capturadas, por default no se hace NADA con la excepción solo nos limitamos a devolver verdadero o falso para indicar si la operación se produjo con éxito o no.
La última excepción ocurrida se guarda en la instancia del manejador de BD (es del tipo TSQLStatementManager) pero puede ser accedida desde la instancia de la clase TEntidadConexion. Basándome en el proyecto TestORM que tiene una única conexión, osea, una única instancia de TEntidadConexion denominada SingleConnection podrías hacer lo siguiente...
procedure TFrmPrincipal.btnAgregarTipoDocumentoCl ick(Sender: TObject); var unTipoDoc: TTipoDocumento; begin unTipoDoc:= TTipoDocumento.Create; unTipoDoc.Descripcion := 'Documento Nacional de Identidad'; unTipoDoc.DescripcionReducida := 'DNI'; unTipoDoc.Observaciones := 'Nada'; if not unTipoDoc.Guardar then ShowMessage(SingleConnection.LastException.Message); unTipoDoc.Free; end;
Ahora imaginemos que quieres hacer algo según motor de BD que estas usando y pretendes tomar el número de excepción y mostrar un mensaje en español y personalizado. Por el error que habías tenido podrías mostrar algo como "Clave duplicada, por favor, controle el valor del campo XXX"
Para atrapar las excepciones y realizar algún trabajo propio tienes que definir un método del tipo TOnExceptionEvent: TOnExceptionEvent = procedure(e: exception) of object;
En mi caso voy a definir este método en la clase principal del proyecto TestORM: procedure TFrmPrincipal.AtraparErrores(e: exception); begin //Aca debería haber un trabajo mas fino ShowMessage(e.Message); end;
Y, finalmente, hay que hacer que nuestro nuevo método sea el método a invocarse cada vez que ocurre una excepción, eso se hace asignando la variable "OnuTestEntidadesException" de uTestEntidades (código generado). Para eso modificamos el formcreate asi:
procedure TFrmPrincipal.FormCreate(Sender: TObject); begin uDataModule.sDataBase := 'localhost:c:\Desarrollos\Delphi\DelphiORM\DelphiORMTest\Datos\DelphiORM.fdb'; SingleConnection := TFabricauTestEntidades.CrearNuevaEntida dConexion(true); OnuTestEntidadesException := AtraparErrores; end;
Aquí es donde digo que se podría hacer algo mejor... por ejemplo podríamos construir una clase que se agregue al pool de clases específicas por motor de BD y en esa clase (que implementaría TOnExceptionEvent) preguntar específicamente por los códigos que retorna el motor. Para Firebird solo conozco dos: La excepción número 335544466 que se da al eliminar un registro que está siendo usado y las excepciones 335544548 y 335544665 que significan clave duplicada.
El grupo tiene un lugar para que haya contribuciones de usuarios por si alguien la quiere hacer.
Saludos cordiales
|