Hi zusammen
TQueryResultClass arbeitet schon länger zur vollkomenen Zufriedenheit - das Problem, das ich mit dem Threadtitel angesprochen habe, war: Gäbe es eine
OOP-Lösung, um TQueryResultClass zu ändern? Änderungsziel: Gleiches Funktionieren, wie ursprünglich implementiert, aber mit andern Bezeichnern. Aber erstmal, was TQueryResultClass tut (und mehr hat diese Klasse auch nicht zu tun):
Delphi-Quellcode:
procedure TFDMySQLDml.SelectBildDaten(FCategoryKey : Integer);
var SQLString:
String; Kath_Id : integer;
begin
Kath_Id := FCategoryKey;
SQLString := DefineBildSQL3(Kath_Id);
// Liefert den SQL-String zurück
FDQueryMain.Connection := Self.FDConnectionMySql;
FDQueryMain.Close;
FDQueryMain.SQL.Text := SQLString;
FDQueryMain.Params.CreateParam(ftInteger, '
Kath_Id', ptOutput);
FDQueryMain.Params[0].AsInteger := Kath_Id;
FDQueryMain.Open;
FDQueryMain.First;
While (
Not FDQueryMain.Eof)
do
begin
FQueryResult := TQueryResultClass.Create(Self);
FQueryResult.IdBild := (FDQueryMain.FieldByName('
BildId').AsInteger);
[QUOTE]FQueryResult.BildDescribeTabelle.BilddesribeID := FDQueryMain.FieldByName('
BildDescribeId').AsInteger;[/QUOTE]
FQueryResult.BildDescribeTabelle.bildkatID := FDQueryMain.FieldByName('
bildkatID').AsInteger;
FQueryResult.BildDescribeTabelle.BildName := FDQueryMain.FieldByName('
BildName').AsString;
FQueryResult.BildDescribeTabelle.BildBeschreibung := FDQueryMain.FieldByName('
Bildbeschreibung').AsString;
FQueryResult.BildDescribeTabelle.BildLegende := FDQueryMain.FieldByName('
Bildlegende').AsString;
FQueryResult.KategoryTabelle.Kategory := FDQueryMain.FieldByName('
Kategorie').AsString;
FDQueryMain.Next;
FCategoryBildlist.Add(FQueryResult);
// Die Records in TQueryResultClass müssen überprüft werden.
end;
FDQueryMain.Close;
end;
Wie ersichtlich ist: Weder das
Query noch TQueryResultClass verfügen in dieser Abfrage über einen Stream für Blobdaten. Interesieren tun hier nur gerade mal die Begleitdaten zum Bild.
Das besondere, weswegen es TQueryResultClass überhaupt gibt, sind seine Bilder-Propertis:
Delphi-Quellcode:
property Thumbnail: TMemoryStream read GetThumbnail write SetThumbnail;
property Bitmap: TMemoryStream read GetBitmap write SetBitmap;
Die beiden Getter, aam Beispiel von GetThumbnail:
Delphi-Quellcode:
function TQueryResultClass.GetThumbnail: TMemoryStream;
var AUser, APass : String;
begin
if not Assigned(FThumbnail) then
begin
FThumbnail := TMemorystream.Create;
Result := FillThumbnail(FThumbnail);
end else
Result := FThumbnail;
end;
Die Funktion Fillthumbnail:
Delphi-Quellcode:
function TQueryResultClass.FillThumbnail(var Thumbnail: TMemoryStream):TMemoryStream;
var
BildID: Integer;
BlobStream: TStream;
LNull: string;
SQLString: string;
begin
BildID := Self.FidBild;
SQLString := 'SELECT Bildtabelle.Thumbnail as Thumbnail FROM Bildtabelle WHERE Bildtabelle.idBild = :BildID';
FDMySQLDml.FDQueryMain.SQL.Text := SQLString;
FDMySQLDml.FDQueryMain.Params.CreateParam(ftInteger, 'BildID', ptInput);
FDMySQLDml.FDQueryMain.Params[0].AsInteger := BildID;
FDMySQLDml.FDQueryMain.Open;
FDMySQLDml.FDQueryMain.First;
while not FDMySQLDml.FDQueryMain.Eof do
begin
if not FDMySQLDml.FDQueryMain.FieldByName('Thumbnail').IsNull then
begin
BlobStream := FDMySQLDml.FDQueryMain.CreateBlobStream(FDMySQLDml.FDQueryMain.FieldByName('Thumbnail'), bmread);
BlobStream.Position := 0;
FThumbnail.CopyFrom(BlobStream, Blobstream.Size);
BlobStream.Free;
FDMySQLDml.FDQueryMain.Next;
Result:= FThumbnail;
end
else
begin
LNull := 'Kein Thumbnail vorhanden';
FThumbnail.WriteBuffer(LNull, SizeOf(LNull));
end;
end;
FDMySQLDml.FDQueryMain.Close;
end;
Das ist das, was geschieht, wenn zur Darstellung der Datensätze auch auf die Bildpropertys von TQueryResultClass zugegriffen wird.
Und nochmal zur Übereinstimmung von Klassen-/Feld und Tabellen/Feldnamen: Der Klasse tuts nicht weh, wenn ihre Felder gleich heissen, wie diejenigen der Tabelle, und zu Fehlfunktionen kann es auch nicht kommen. Aber was liest sich besser:
Delphi-Quellcode:
FQueryResult.BildDescribeTabelle.bildkatID := FDQueryMain.FieldByName('bildkatID').AsInteger;
// oder
FQueryResult.Id := FDQueryMain.FieldByName('bildkatID').AsInteger;
Von den drei beteiligten Tabellen hat jede eine Id als Primärschlüssel und eine als Fremdschlüssel,und alle sind sie wichtig. Bei übereinstimmenden Namen kannst du in der Zuweisung nicht irren, bei grundsätzlich verschiedenen Namen hingegen schon.
Zitat von DeddyH:
Zitat:
Je mehr ich lese, desto mehr frage ich mich: wozu das Ganze? Soll das ein ORM werden/sein? Dann haben IMO die Tabellen- bzw. Feldnamen in den Objekten nichts zu suchen, die Objekte sollte es nicht interessieren, woher die Daten kommen oder wohin sie gehen, dafür ist eine Schicht zuständig. So wie ich es sehe bringt der ganze Aufwand momentan 0% Nutzen (sofern ich das richtig überblicke, ich kann mich auch irren), sondern sorgt eher für Verwirrung.
Gewissermassen ja. Das ganze, insbesondere der Teil mit dem Nachladen der Bilddaten, ist unter anderem mit deiner tatkräftigen Mithilfe (auf Delphi Treff) entstanden. Dein Kommentar damals: "Ein Mini-Orm".
Ein ORM bildet ja eine komplette Datenbank mit Hilfe von zB. Delphi-Objekten ab. Aber eben eine
komplette Datenbank. Meine Klasse gestattet das Nachladen der Bilddaten bei Bedarf und das Iterieren durch die Ergebnismenge bei geschlossenem
Query oder sogar geschlossener Verbindung, mehr nicht.
Gruss
Delbor