PDA

Ver la Versión Completa : Ejemplo de reglas en capa intermedia


Ulises
05-08-2003, 20:09:33
Hola,

Tengo un Remote Data Module : SQLConnection --> SQLQuery --> DataSetProvider, con sus correspondientes sql, campos persistentes identificacion de claves, upwherechanged, etc.

El Remote data module esta en un servidor con WinNT y lo subo mediante una dll.

En el cliente un DcomConnection --> ClientDataset.

Lo que quiero es si me pueden dar un ejemplo de reglas de negocios que puedo colocar en la capa intermedia o sea en la DLL, yo tengo reglas en la base de datos y muy pocas en la capa cliente, pero no he podido colocar reglas en el remote data module.

Gracias de antemano.

Ulises

guillotmarc
05-08-2003, 20:25:18
Hola

Basicamente las mismas que tienes en la Base de Datos. Por ejemplo si tienes un trigger el cual al dar de alta una venta, decrementa el stock de los productos asociades, entonces puedes quitar el trigger, y hacer la salida de Stocks en código Delphi desde la aplicación de la capa intermedia (en el AfterInsert del DataSet correspondiente)

Ventajas : Debido a la mayor potencia de Delphi sobre los lenguajes de triggers y procedimientos almacenados, podrás hacer reglas más complejas, más legibles y más faciles de mantener. NOTA : Acuerdate de englobar las modificaciones que realiza la regla de negocio en una transacción, para asegurar que se cumpla toda la regla, o no se haga nada.

Además podrás hacer reglas que impliquen más de una base de datos, cosa que no puedes hacer directamente estableciendo las reglas en la base de datos. Así como realizar tareas adicionales independientes de las Bases de Datos. Por ejemplo, supón que cuando un producto baja su stock por debaje de una cantidad, queremos avisar a un Administrador. Enviar un e-Mail no lo puedes programar estableciendo la regla en la Base de Datos, lo podrías hacer en el Cliente, pero es mucho más limpio hacerlo en la capa intermedia (cuanto menos haga el cliente, mejor).

Saludos.

Ulises
05-08-2003, 20:39:01
Gracias Marc, por tu pronta respuesta, en realidad habia colocado varios post pero no habia tenido respuesta alguna y estaba un poco desilusionado pero he renacido nuevamente.

Estoy completamente de acuerdo en tus apreciaciones, ahora con respecto a las transacciones, notarás que yo ocupo sqlConnection, la cual en sus propiedades le digo el tipo de transaction, es decir Read Commited en mi caso; la transaction estaría implicita en este caso?

Al tener Provider, tendría que efectuar las reglas en el BeforeApplyUpdates?


Gracias Marc por tu ayuda.

Ulises

guillotmarc
06-08-2003, 12:43:27
Hola.

En efecto, siempre hay una transacción implícita. Pero si en algún momento quieres ejecutar dos sentencias dentro de una misma transacción, puedes abrir una transacción manualmente. (Con el StartTransaction del SQLConnection).

Sobre el evento en el que colocar las reglas, me parece más correcto el BeforeUpdateRecord, puesto que se ejecuta una vez para cada registro a modificar, además en el parámetro UpdateKind tienes si es una inserción, modificación o borrado, así como los valores de los campos antes de aplicar la modificación y después. Con lo que tienes todos los datos para aplicar una regla de negocio.

NOTA : La verdad es que nunca he utilizado una capa intermedia, así que esto es lo que yo haría, pero no lo he probado.

Saludos.

Ulises
06-08-2003, 14:44:51
Gracias MArc por tu respuesta, lo haré y si me resulta te prometo que publicaré mis experimentos.

Saludos


Ulises

Ulises
06-08-2003, 20:51:16
Hola Marc,

Segui tus consejos y puse en el evento BeforeUpdateRecort el siguiente código:

if (UpdateKind <> ukDelete) and
(SourceDS.FieldByName('ER_CODCIU').Value = 0) then
raise Exception.Create('Debe seleccionar ciudad');

En el momento de realizar el ApllyUpdate por el lado del cliente, me sale un error que dice que no se puede realizar la operación en un dataset cerrado.

Tengo entendido que los SqlQueries en el rdm estan cerrados y que se abren cuando el cliente asi lo requiere, grabe mi dll con las tablas abiertas pero aún asi me sale el mismo error.

Alguna idea????


Gracias de antemano

Ulises

guillotmarc
06-08-2003, 21:28:10
Hola.

En efecto, los querys del RDM són abiertos automaticamente por los Providers, por lo que no hace falta que los dejes abiertos (es más quizá te puede traer problemas, puesto que quizá no pueda actualizar los datos para refrescarlos, ya que se encuentre con el dataset abierto, aunque no estoy seguro).

En todo caso no tiene nada que ver con el problema. Las modificaciones no se realizan sobre esos querys (piensa que que los querys dbExpress són de solo lectura). Las actualizaciones són enviadas directamente por el provider, a la base de datos mediante una sentencia INSERT / UPDATE / DELETE ejecutada directamente sobre el SQLConnection.

El problema tiene que venir en tu código, al evaluar SourceDS.FieldByName('ER_CODCIU').Value. Puesto que como puedes ver en la ayuda, SourceDS a veces puede ser nil.

SourceDS contiene los valores del DataSet antes de que se hiciera ningún cambio. Entonces si estás haciendo una inserción ¿ que hay en SourceDS ? ¿ Un DataSet vacío ?.

Tienes que consultar el DeltaDS que apunta al registro con los cambios que se van a realizar.

NOTA : Para comprobar los datos antes de insertarlos, está bien utilizar el evento BeforeUpdateRecord. Pero para otras cosas será mejor utilizar el AfterUpdateRecord, por ejemplo si quieres actualizar la tabla de Stocks al añadir un producto en una Venta, lo debes hecer en el AfterUpdateRecord, para asegurarte de que solo se realiza si el registro ha sido añadido correctamente a la Base de Datos.

Saludos.

Ulises
07-08-2003, 14:08:12
Gracias Marc por tus consejos, ya pude sacar adelante mi primera regla de negocios en capa intermedia.

Slds

Ulises