Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf (https://www.delphipraxis.net/188236-dataset-immer-wieder-neu-erstellen-create-free-oder-ein-mal-bei-bedarf.html)

norwegen60 12. Feb 2016 10:33

Datenbank: MsSQL • Version: 2008 R2 • Zugriff über: ADO

Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Hallo zusammen,

bei uns in der Firma gibt es gerade Diskussionen um zwei verschiedene Philosophien, wie auf Daten zugegriffen werden kann.

Philosophie 1:
In einem Datenmodul wird fix ein TAdoDataset platziert, das bei ersten Gebrauch geöffnet wird und danach über ähnliche Schnittstellen wie unten angesprochen wird


Philosophie 2:
Das Dataset wird bei jedem Bedarf erstellt, die gesuchten Daten an ein fDataset übergeben und das Dataset danach wieder freigegeben.
Delphi-Quellcode:
 TBaseDataObject = Class
  Private

    /// <summary>
    /// backing field number list, will be filled each time data is loaded
    /// </summary>
    fNumberList: TIntegerList;

    /// <summary>
    /// backing field for where conditions to get data
    /// </summary>
    fWhereConditions: TStringList;

    /// <summary>
    /// backing field for order statements to get data
    /// </summary>
    fOrderStaments: TStringList;

    /// <summary>
    /// backing field for dataset for binding in grids
    /// </summary>
    fDataSet: TCustomClientDataSet;

....

Function TBaseDataObject.GetDataSet: TADODataSet;
Var
  lRealDataSet: TADODataSet;
Begin
  lRealDataSet := TADODataSet.Create(Nil);
  lRealDataSet.Connection := GetConnection();
  lRealDataSet.BeforeOpen := TDataTableOpenEvents.DataTableBeforeOpen;
  Result := lRealDataSet;
End;

// -----------------------------------------------------------------------------
Procedure TBaseDataObject.Refresh;
Var
  lRealDataSet: TADODataSet;
  li: Integer;
  workingOnLocalDatabase: String;
Begin
  fDataSet.DisableControls; // avoiding flicker

  lRealDataSet := GetDataSet;


  lRealDataSet.CommandText := getSelectStatement;
  fDataSet.EmptyDataSet;
  fNumberList.Clear;

  Try
    lRealDataSet.Open;
    If lRealDataSet.RecordCount > 0 Then
    Begin
      lRealDataSet.First;
      Repeat
        fDataSet.Append;
        fNumberList.Add(StrToIntDef(lRealDataSet.FieldByName(fPkName).Value, -1));

        for li:=0 to pred(lRealDataSet.FieldCount) do { Alle Felder kopieren }
        begin
          fDataSet.FieldByName(lRealDataSet.Fields[li].FieldName).Value := lRealDataSet.Fields[li].Value;
        end;

        fDataSet.Post;
        lRealDataSet.Next;
      Until (lRealDataSet.Eof);
    End
    Else
      Logger.Debug('TBaseDataObject.Refresh', 'No data for table %s [%s]', [fTableName, getSelectStatement]);
  Except
    On E: Exception Do
      Logger.Fatal('TBaseDataObject.Refresh', 'Could not get field definitions for table %s, Field %S Exeption: %s', [fTableName, lRealDataSet.Fields[li].FieldName, E.Message]);
  End;
  fDataSet.First;
  DataBase.FreeDataSet(lRealDataSet);
  fActive := true;
  fDataSet.EnableControls;
End;
Der Unterschied könnte auch darauf reduziert werden, dass das Dataset in einem Fall einmal geöffnet wird und dann immer wieder verwendet wird und im anderen Fall jedes mal befreit und wieder neu erstellt wird.

Welche Auswirkungen hat die dauernde Neuerstellung auf Laufzeit und Netzbelastung?
Was spricht aus eurer Sicht für / gegen die eine oder andere Methode?

Wäre froh um ein paar unabhängige Meinungen

Danke
Gerd

Bernhard Geyer 12. Feb 2016 12:04

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Solange du eh immer alles in ein ClientDataset kopierst ist das erzeugen der TADODataSet-Instanz irrelevant.
ich weiß nicht wie das bei deiner eingesetzten ADO/dbGo-Version ist. Bei D6 wurde beim Open relaiv viel Zeit verbraten um zu bestimmen ob es AutoInc-Felder gibt.
Nachdem wir dbGO weggeschmissen haben und direkt mit den ADO-Interfaces arbeiten sind wir merklich schneller geworden (obwohl wir auch viel Kopieraktionen haben)

nahpets 12. Feb 2016 12:19

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Hinter einem DataSet kann eine beliebig komplizierte Abfrage stecken. Damit kann beim Laden der Daten eine nicht unerhebliche Laufzeit entstehen.

Wenn ich eine Abfrage nur einmal brauche, sie auswerte und dann nie wieder (mit den gerade aktuellen Daten) benötige, spricht nichts gegen ein Erstellen und nach Verarbeitungsende dem Freigeben eines DataSets.

Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt, würd' ich sie nicht bei jedem Zugriff neu erstellen, sondern per Cursor... (ggfls. Filter) navigieren.

Datenbankverbindungen öffne ich beim ersten Gebrauch und schließe sie, wenn ich weiß, dass ich sie nicht mehr benötige.

Also z. B. beim Programmstart und beim Programmende.
Kann ein Programm alternativ auf unterschiedliche Datenbanken zugreifen, wird die Datenbankverbindung halt vor dem ersten Zugriff geöffnet und beim Datenbankwechsel die aktuelle Datenbankverbindung geschlossen und die neue Datenbankverbindung geöffnet.
Hierbei erstelle ich die entsprechende Komponente jedoch nicht jedesmal neu bzw. gebe sie frei, sondern verwende sie wieder.

Anders mache ich es nur, wenn die gesamte Datenbankzugriffsschicht in einer Klasse gekapselt ist und das Erstellen bzw. Freigeben aller Datenbankzugriffskomponenten... innerhalb dieser Klasse erfolgt. (Dies sind dann eher Batchprogramm, die die Daten eh nur einmalig benötigen.)

Bernhard Geyer 12. Feb 2016 12:27

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Zitat:

Zitat von nahpets (Beitrag 1330154)
HWird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt, würd' ich sie nicht bei jedem Zugriff neu erstellen, sondern per Cursor... (ggfls. Filter) navigieren.

Das kannst du aber nur bei Daten machen die sich nicht währen der Laufzeit des Programm verändern (Neu/Geänderte/Gelöschte Datensätze)

nahpets 12. Feb 2016 12:29

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1330155)
Zitat:

Zitat von nahpets (Beitrag 1330154)
Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt, würd' ich sie nicht bei jedem Zugriff neu erstellen, sondern per Cursor... (ggfls. Filter) navigieren.

Das kannst du aber nur bei Daten machen die sich nicht währen der Laufzeit des Programm verändern (Neu/Geänderte/Gelöschte Datensätze)

Ja, natürlich, deshalb schrieb ich ja auch
Zitat:

Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt...
;-)

Bernhard Geyer 12. Feb 2016 12:33

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Zitat:

Zitat von nahpets (Beitrag 1330156)
Zitat:

Zitat von Bernhard Geyer (Beitrag 1330155)
Zitat:

Zitat von nahpets (Beitrag 1330154)
Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt, würd' ich sie nicht bei jedem Zugriff neu erstellen, sondern per Cursor... (ggfls. Filter) navigieren.

Das kannst du aber nur bei Daten machen die sich nicht währen der Laufzeit des Programm verändern (Neu/Geänderte/Gelöschte Datensätze)

Ja, natürlich, deshalb schrieb ich ja auch
Zitat:

Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt...
;-)

Du hast eine Datenmenge geholt und diese Repräsentiert einen Zustand x.
Diese wird auch wenn man über Filter und Curser arbeitet auch in 5 Stunden diesen veralteten Zustand haben.
Das was evtl. bei "Datenbanken" wie dBase und Co. funktioniert wird bei einer richtigen DB nicht funktieren. Hier musst du nochmal die Datenbank abfragen.

Sir Rufo 12. Feb 2016 12:37

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Eigentlich sollte man die Use-Cases trennen.

Man hat ein DatenModul mit der Connection und x DataSets die auschliesslich als Lookup verwendet werden.

Delphi-Quellcode:
TBaseDataModule = class( TDataModule )
  Connection: TADOConnection;
  PersonLookup: TADOTable;
  ...
end;
Für jeden Use-Case baut man sich jetzt ein eigenes DataModule. Da packt man dann alle Tabellen/Abfragen drauf und verknüpft diese, wie man das nun so braucht. Für die Verbindung nimmt man sich das zentrale
Delphi-Quellcode:
TBaseDataModule
.

Kommt jetzt ein Formular daher, dann erzeugt sich dieses Formular eine Instanz von dem passenden Use-Case und verbindet die DataSets mit dem Grid/Edits/... whatever.

Dann kommt man auch nicht in die Notlage, dass sich 2 Formulare gegenseitig auf den füssen stehen, weil beide auf die gleichen DataSets zugreifen.

nahpets 12. Feb 2016 12:49

AW: Dataset immer wieder neu erstellen (create/free) oder ein mal bei Bedarf
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1330157)
Zitat:

Zitat von nahpets (Beitrag 1330156)
Zitat:

Zitat von Bernhard Geyer (Beitrag 1330155)
Zitat:

Zitat von nahpets (Beitrag 1330154)
Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt, würd' ich sie nicht bei jedem Zugriff neu erstellen, sondern per Cursor... (ggfls. Filter) navigieren.

Das kannst du aber nur bei Daten machen die sich nicht währen der Laufzeit des Programm verändern (Neu/Geänderte/Gelöschte Datensätze)

Ja, natürlich, deshalb schrieb ich ja auch
Zitat:

Wird eine unveränderte Datenmenge jedoch wiederholt in gleicher Form benötigt...
;-)

Du hast eine Datenmenge geholt und diese Repräsentiert einen Zustand x.
Diese wird auch wenn man über Filter und Curser arbeitet auch in 5 Stunden diesen veralteten Zustand haben.
Das was evtl. bei "Datenbanken" wie dBase und Co. funktioniert wird bei einer richtigen DB nicht funktieren. Hier musst du nochmal die Datenbank abfragen.

@Bernhard Geyer
Bei dem von Dir Beschriebenen wird sie aber nicht in unveränderter Form wieder benötigt, sondern es wird eine aktuallisierte Abfrage benötigt.

Wenn ich also die Datenmange x benötige und daraus konsistent zueinander passende Reports erstellen muss, oder mehrere Zielsysteme mit den Daten vom Zeitpunkt x versorgen muss...
Würde ich in so einem Fall einen DataSet mehrfach erstellen und wieder wegwerfen, könnte ich die Konsistenz der Daten nicht (zwingend) sicherstellen, da sie sich eben geändert haben können, ich aber die Daten von genau dem Zeitpunkt x benötige.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:00 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