AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Die Sache mit dem Listenproperty

Ein Thema von Delbor · begonnen am 1. Mär 2017 · letzter Beitrag vom 4. Mär 2017
Antwort Antwort
Seite 3 von 3     123   
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: Die Sache mit dem Listenproperty

  Alt 3. Mär 2017, 09:55
Hi Sakura

Genaugenommen wird die Anfrage bei jedem lesezugriff auf das Property ausgeführt. Die Alternative wäre, die SQL-Anfrage ausserhalb des Datenmoduls dann da ausführen, wo ich sie brauche. Zum Bleistift in einem PageControl zur Anzeige von Metadaten auf der Mainform. Damit hätte ich dann eine weitere Prozedur in der Mainform, die es allenfalls zu ändern (und erstmal zu finden) gibt. Und wenn ich mehrere Informationen, für deren Beschaffung das Datenmodul zuständig ist, von ausserhalb abfrage, habe ich auch ausserhalb eine entsprechende Anzahl Methoden, die mir diese Infos beschaffen - und sollte sich irgendwas ändern, zum Bleistift an der Datenbank/Tabellenstruktur, darf ich alll diese Methoden ausserhalb des Datenmoduls da ändern, wo ich sie angelegt habe. Das muss nicht zwingend die Mainform sein, das kann eine andere Form oder ein Frame - im schlimmsten Fall pro Prozedure/SQL-Statement - sein. Wenn ich das im alles im Datenmodul habe, muss ichs auch nur da ändern.
Auch wenn ich Methoden von ausserhalb nur aufrufe - wenn sich die Art des Aufrufens ändert (Parameter können sich ändern etc), darf ich alle diese Aufrufe an verschiedenen Stellen des Programmes ändern.

Eine gute Richtlinie ist es aber immer so zu entwickeln, als könnten solche Informationen an mehreren Stellen gleichzeitig gebraucht werden, das macht spätere Erweiterungen leichter. Auch bei Desktopanwendungen ist Multi-Threading schon lange keine Ausnahme mehr.

Ja eben: genau deswegen ist es besser, das Datenmodul stellt die Infos als Propery bereit. Ansonsten müsste jede dieser Stellen das SQL-Statement aufrufen. Das Statement selbst, bzw. desse Ausführung, dürfte vo der Performance her kaum ins Gewicht fallen.
Und nochmals: sollte ich mit einem andern als dem Hauptthread auf das Property zugreifen, dann nur in einer Criticalsection.

Anders sieht es allerdings aus, wenn ich meine BilderDatenbank abfrage: Hier werden die Ergebnisse pro Datensatz in eine Klasse geschrieben (und diese in eine Objectliste gepackt), so dass die Abfrage selbst im Normalfall nur einmal durchgeführt werden muss.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch

Geändert von Delbor ( 3. Mär 2017 um 10:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#22

AW: Die Sache mit dem Listenproperty

  Alt 3. Mär 2017, 10:44
Hi,

leider hast du offenbar überhaupt nicht verstanden, was ich geschrieben habe.

Genaugenommen wird die Anfrage bei jedem lesezugriff auf das Property ausgeführt.
Korrekt.
Die Alternative wäre, die SQL-Anfrage ausserhalb des Datenmoduls dann da ausführen, wo ich sie brauche.
Diese Änderung habe ich nicht einmal angedeutet, wäre mir auch nie in den Sinn gekommen.
genau deswegen ist es besser, das Datenmodul stellt die Infos als Propery bereit.
Datenmodul ist eine einfache, nicht sehr schöne Lösung, aber praktikabel. Da wollte ich auch nicht ran.
Und nochmals: sollte ich mit einem andern als dem Hauptthread auf das Property zugreifen, dann nur in einer Criticalsection.
Also zurück zu meiner Idee, welche DeddyH auch schon gut als Code gezeigt hat. Warum nicht einfach EINMAL die Daten ermitteln und anschließend einfach als fertige Liste zur Verfügung stellen. Gerne auch als TStrings - die Nach-/Vorteile sind ja bekannt. Dann würdest Du auch keine CS in multi-threading benötigen (mit der Einschränkung keiner ändert jemals die Werte nach dem initialen Befüllen).

Warum lädst Du mit jeder Anfrage sich nicht ändernde Daten neu? Das ist grundsätzlich kein gutes Vorgehen. Selbst wenn es schnell geht, macht es schnell einen spürbaren Unterschied in der Geschwindigkeit, je nachdem, wie oft das gemacht wird.

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Die Sache mit dem Listenproperty

  Alt 3. Mär 2017, 12:23
Hi Sakura

Ich hab mir DeddyHs Atwort zuunterst auf Seite eins nochmal angesehen. Meinst du die? Das könnte dann etwa so umgesetzt werden:
Delphi-Quellcode:
function TFDMySQLDml.GetContentmasterTables: TStringlist;
  var SqlString : String; I: integer;
begin
  if FContentmastertables = Nil then then
  begin
    FContentmastertables := Tstringlist.Create;
    SqlString := 'SHOW TABLES';
    FDQueryMain.Open(SqlString);
    FDQueryMain.First;
    while not FDQueryMain.Eof do
    begin
      FContentmastertables.Add(FDQueryMain.Fields.Fields[0].AsString);
      FDQueryMain.Next;
    end;
  FDQueryMain.Close;
  end;
  Result := (FContentmastertables);
 end;
Stimmt, so wird die Abfrage nur einmal durchgeführt, vorausgesetzt die Tabelle ändert sich nicht. Was sie allerdings zumindest zur Laufzeit nie tun sollte.

Gruss
Delbor

PS: Oder meinst du etwa dies aus Beitrag 18:
Zitat:
constructor TDingens.Create;
begin
FTablenames := TStringList.Create;
FillTablenamesFormSomewhere(FTablenames);
end;
Das gefällt nun mir nicht wirklich. Und DeddyH selbst wohl auch nicht.
Hier greift das Datenmudul nach oben*, was bei einer Trennung der Programmlogiken in verschiedene Schichten eben vermieden werden soll.

*Zumindest, wenn ich den Aufruf richtig interpretiere.
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch

Geändert von Delbor ( 3. Mär 2017 um 12:39 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#24

AW: Die Sache mit dem Listenproperty

  Alt 3. Mär 2017, 17:31
Kombinier doch einfach alles:
Delphi-Quellcode:
type
  TDingens = class
  private
    FTablenames: TStringList;
    function GetInternalTablenames: TStringList;
    function GetTablenames(Index: integer): string;
    function GetTablenameCount: integer;
    property InternalTablenames: TStringList read GetInternalTablenames;
  public
    destructor Destroy; override;
    property TablenameCount: integer read GetTablenameCount;
    property Tablenames[Index: integer]: string read GetTablenames;
  end;

...

destructor TDingens.Destroy;
begin
  FTablenames.Free;
  inherited;
end;

function TDingens.GetInternalTablenames: TStringList;
begin
  if not Assigned(FTablenames) then
    begin
      FTablenames := TStringList.Create;
      (* Hier jetzt der Code zum Befüllen *)
    end;
  Result := FTablenames;
end;

function TDingens.GetTablenames(Index: integer): string;
begin
  //Hier wird auf die interne Property zugegriffen
  Result := InternalTablenames[Index];
end;

function GetTablenameCount: integer;
begin
  //Hier auch
  Result := InternalTablenames.Count;
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: Die Sache mit dem Listenproperty

  Alt 4. Mär 2017, 09:37
Hi DeddyH

Hier habe ich zumindest unter FireDac ein Problem. In einer definierten Verbindung kann ich genau eine Datenbank angeben - zumindest muss ich das so interpretieren, nachdem Embarcadero in allen Definitionsbeispielen immer genau eine Datenbank angibt und dabei nichts von einer Verbindung zu mehreren Datenbanken dazuschreibt. Einzig Verbindungspooling bleibt da möglich zu sein.
Aber wie ich das bis jetzt verstanden habe, ist ein Pool eine Menge verschiedener Verbindungen, und ich denke, so würde dies auch der Server interpretieren. Und das führt dann dazu, dass jede Verbindung in diesem Pool aus Sicht des Servers ihre eigenen Sessionvariablen hat.

Als Beispiel die Veränderung des Wertes FMaxAllowedPacket. Die entsprechende Tabelle zeige ich mir so an:

'SELECT Variable_Value FROM performance_schema.SESSION_VARIABLES WHERE VARIABLE_NAME = ''MAX_ALLOWED_PACKET'''; Den Wert kann ich dann so ändern:

FDQueryMain.SQL.Text := 'SET @@global.Max_ALLOWED_PACKET = '+ IntToStr(Variable_Value);

Das akzeptiert der Server, weil es sich dabei um den Wert handelt, der für meine Verbindung gilt. Zumindest interpretie ich das so, da ich keine Rückmeldung wegen fehlender Rechte erhalte.
Ob das wirklich tut, was es soll, kann ich erst kontrollieren, wenn das Programm mal ohne AV startet.
Unter DBExpress hats funktioniert...

Führe ich nun aber ein einfaches 'Show Tables' aus, erhalte ich in jedem Fall die Tabellennamen der DB, mit der ich aktuell Verbunden bin. Das heisst aber, dass ich unter der aktuellen Verbindung nur lesend und mit einem SELECT-Statement auf die Serverdatenbank und deren Tabellen zugreifen kann.
Die Tabellennamen in in der DB performance_schema erhalte ich so nicht.

Aber nachdem ich mir deinen Code nochmal angeschaut habe: Ich bin offensichtlich noch nicht ganz wach. Dein Code zielt eigentlich auf das DRY-Prinzip ab. Mit meinem kurz davor geposteten Quelltext müsste ich die Passagen zur Erstellung der Liste jedesmal wiederholen.
Trotzdem lasse ich die ersten 3 Abschnitte jetzt mal stehen; vielleicht hat ja jemand eine Lösung, wie das Problem behoben werden könnte.

Auf jeden Fall mal vielen Dank für deinen Code!

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz