Cita:
Empezado por Al González
Hola Pablo, José.
Al González.
|
Al!!! Sos la primer persona que entiende mi problema y me da una posible solución!! Mil gracias!!!
En realidad, no trabajo con Datasnap, sino con dbExpress, y estoy haciendo unas clases para poder heredar a partir de ellas.
Me basé en
este link que me sirvió muchisimo.
Hice la capa de acceso a datos con un DM y un
TSQLQuery y le puse
TBusinessObjectDM. Luego un DM con dos
TDataSetProvider y dos
TClientDataSet, uno para listar todos los registros de la tabla y otro para levantar exclusivamente el registro a editar, a este DM le puse TBusinessObject. De estos 2 objetos voy a heredar el resto de mis Entidades del Negocio.
Hasta acá todo bien, hasta que quise implementar un
TBusinessObjectMD (master/detail) que me encontré con este problema.
Por más que sea "norma", no me parece bonito nombrar un campo con el nombre de la tabla. O sea, que la tabla Clientes, tenga como ID el campo IDCliente. Al trabajar de esta forma, puedo asumir que todas las tablas tienen un campo
ID que identifica a cada registro, me parece lo más coherente. Luego los fk si son nombres compuestos, como por ejemplo IDMASTER para apuntar a la tabla MASTER.
No soy muy amigo de redefinir métodos ni de persistir campos, así que voy a ver de "automatizar" las ProviderFlags, especificandole al DM la FK.
Lo que me está frenando ahora es que no puedo hacer
Select *, id as idmaster from master where id=123 Alguna idea? no quiero tener que andár poniendo todos los campos en el sql (porque si agrego un campo a la tabla, tengo que andar tocando en varios lugares)
Tambien me pasaron una solución que es utilizar otro componente al que se le puede especificar la relación, pero no me puse a verlo:
Código Delphi
[-]unit MySqlDataSet;
interface
uses
Windows, Messages, SysUtils, Classes, DB, SqlExpr;
type
TMySQLDataSet = class(TSQLDataSet)
private
FLinks : TStrings;
procedure SetLinks(Value : TStrings);
protected
procedure GetDetailLinkFields(MasterFields, DetailFields : TList);
override;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
published
property Links : TStrings read FLinks write SetLinks;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('My', [TMySQLDataSet]);
end;
constructor TMySQLDataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FLinks := TStringList.Create;
end;
destructor TMySQLDataSet.Destroy;
begin
FLinks.Free;
inherited Destroy;
end;
procedure TMySQLDataSet.GetDetailLinkFields(MasterFields, DetailFields:TList);
var
i : integer;
masterName, detailName : string;
masterField, detailField : TField;
masterDS : TDataSet;
begin
MasterFields.Clear;
DetailFields.Clear;
if (DataSource = nil) or (DataSource.DataSet = nil) then Exit;
MasterDS := DataSource.DataSet;
for i := 0 to FLinks.Count-1 do begin
detailName := FLinks.Names[i];
masterName := FLinks.Values[detailName];
masterField := masterDS.FieldByName(masterName);
detailField := Self.FieldByName(detailName);
if (masterField <> nil) and (detailField <> nil) then begin
MasterFields.Add(masterField);
DetailFields.Add(detailField);
end;
end;
end;
procedure TMySQLDataSet.SetLinks(Value: TStrings);
begin
FLinks.Assign(Value)
end;
end.
Bueno, me tomé mi tiempo para responder, quise ponerle la misma dedicación que le pusiste!
Ahora ya estoy encaminado y salí del pozo en el que estaba desde hace unos dias y no me permitia dormir... voy a ponerme a analizar cual es la mejor solución y la comparto.
Saludos!
Pablo