Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   datasnap para sql server??? (https://www.clubdelphi.com/foros/showthread.php?t=73453)

_CALI 24-04-2011 17:10:03

datasnap para sql server???
 
Hola amigos, como siempre un placer...
estuve investigando el tema de aplicaciones de 3 capas con datasnap y me parecio interesante, estoy desarrollnado una aplicacion que es "dos capas"

uso como capa de acceso a datos: el servidor SQL Server 2005,
como capa de inrefaz de susario: delphi 2010,
las reglas de negocio son compartidas en ambas capas, la mayoria de ellas recide en el propio servidor con procedimientos almacenados, etc y el resto en mi propia aplicacion mediante modulos de datos, si bien es cierto puede hacerce en tres capas, me recomendaron en foros y otros articulos q para acceder a sql server lo mejor es ADO y porsupuesto q uso ADO para trabajar con sql server.

el problema es que quiero conectar un TCLientDataSet que radica en un formulario a su respectivo TData SetProvider q radica en el modulo de datos, el TClientDataSet radica en el un formulario (clientes por ejemplo) por que se lanzaran varias instancias del formulario en si.

investigue que en datasnap es posible pero usan un servidor para las reglas de negocio como capa intermedia y componentes DB Express, pero como repito aqui el especialista para sql server es ADO, ademas todavia no quiero migrar mi aplicacion a tres capas

existe la posibilidad de conectara ambos componentes?, que tecnica me recomiendad para que pueda centralizar "casi" toda mi logica de negocio en em modulo de datos sabiendo q se pueden crear varias instancias de los formularios, sin usar modulos de datos remnotos, componentes db express y por ultimo datasnap.

en resumen_: lograr q mi aplicacion se asemeje mas a una de tres capas "siendo de dos"


Muchas gracias de antemano!!!

Al González 24-04-2011 18:17:20

Eso es algo que anteriormente se ha hablado aquí, lo puedes encontrar si buscas "capas lógicas" o "2.5 capas" (que es como osé llamarle).

Es decir, que sí puedes usar componentes proveedores (TDataSetProvider) y conjuntos de datos clientes (TClientDataSet), aunque tu aplicación no necesariamente esté dividida en tres capas y sin dejar de utilizar ADO.

Asignarle un TADOXXX a un TDataSetProvider no tienen ninguna dificultad: los componentes proveedores pueden conectarse con cualquiera de los componentes de acceso a datos que existen.

Si mantienes tus conjuntos de datos clientes fuera del módulo de datos donde se encuentran los proveedores (lo cual me parece bien pensando en esta división lógica de capas), no podrás asociar en tiempo de diseño un TClientDataSet nativo con un TDataSetProvider, pues el primero no tienen propiedad pública "Provider", sino "ProviderName", la cual está pensada para establecer en ella el nombre de un componente proveedor que se encuentre en:

a) un módulo de datos remoto (en el servidor de aplicaciones).
b) el mismo módulo de datos o formulario donde se encuentre el conjunto de datos cliente.

Es decir, que la propiedad ProviderName no sirve para asignar un proveedor que se encuentre en la misma aplicación, pero en un módulo de datos distinto (al menos hasta Delphi 7 es así). No obstante, en tiempo de ejecución, podrías realizar un asignación como esta en el OnCreate del formulario:

Código Delphi [-]
CDS1.SetProvider (dmModuloProveedores.DSP1);

Una recomendación sería, en tiempo de diseño, agregar el conjunto de datos cliente en el módulo de datos de proveedores, asignarle valor a la propiedad ProviderName, agregar los campos persistentes (si fuese el caso) y los parámetros ("Fetch Params") al conjunto de datos. Y, una vez probado que abra y cierre sin problemas, moverlo al módulo de datos o formulario donde realmente quieres tenerlo. Pero eso sí, tendrás que asignarle el proveedor mediante una sentencia de código como la anterior.

Espero haberte orientado.

Al González. :)

_CALI 24-04-2011 19:44:21

excelente!!
 
Eso es precisamente lo que queria lograr, de esa manera mi aplicacion se hara mas flexible y mas ordenada;

Muchas gracias por tu aportación Al Gonzazles, me sirvio de mucho!!!:)

Al González 24-04-2011 20:25:49

Me alegro por ello, _CALI. :)

_CALI 24-04-2011 20:49:00

una ultima acotacion
 
disculpa el abuso jeje.
una ves establecida la conexion del cliente data set que esta el formulario con el proveedor que esta en el modulo de datos...

el cliente data set le pide al proveedor que actualize la tabla con applyupdates(0)

el proveedor ejecuta la instruccion INSERT, UPDATE O DELETE, dependiendo del estado como se encontraba el cliente data set cierto??

cuando creo un registro nuevo todo bien
pero cuando modifico un registro me sale que otro usuario cambio el valor del registro bla bla bla, acuerdate que mi formulario se abre varias veces a la vez, ese problema lo solucionaba ejecutando un TADOCommand para mediante instruccion SQL actualize el valor del registro directamente.

mi pregunta es cual es evento del proveedor (si existe) para poder modificar la instruccion UPDATE o que me recomiendas en tal caso

Muchas Gracias denuevo!!

_CALI 25-04-2011 18:49:04

una posible solucion
 
una posible solucion fue personalizar el metodo de Update del proveedor

Código Delphi [-]
 
procedure TDM.dspVendedoresBeforeUpdateRecord(Sender: TObject;
  SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
  var Applied: Boolean);
begin
if UpdateKind=ukModify then
  begin
    asignar(cmdVendedores, DeltaDS);
    cmdVendedores.Execute;
    Applied:=true;
  end;
 
end;

el procedimiento q se ancarga de pasar los datos del clientedataset al commando :

Código Delphi [-]
 
procedure asignar(comando: TADOCommand; cDataSet: TCustomClientDataSet);
var i: integer;
  begin
   for I := 0 to comando.Parameters.Count - 1 do
           begin
           if  VarIsNull(cDataSet.FieldByName(comando.Parameters.Items[i].Name).Value) then
               comando.Parameters.Items[i].Value := cDataSet.FieldByName(comando.Parameters.Items[i].Name).OldValue
           else
               comando.Parameters.Items[i].Value := cDataSet.FieldByName(comando.Parameters.Items[i].Name).Value;

           end;
  end;


funciona bien pero aun tengo dudas, no se supone q en un campo del cliente data set asi no ingrese un dato es se asume como cadena vacia ''?, me causaba un error al momento de ejecurar el command diciendome q el valor era nulo.

alguna otra recomnedacion gracias de antemano


La franja horaria es GMT +2. Ahora son las 02:55:25.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi