Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Virtuelle Felder in DataSet erstellen (https://www.delphipraxis.net/171730-virtuelle-felder-dataset-erstellen.html)

Morphie 22. Nov 2012 07:55

Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC

Virtuelle Felder in DataSet erstellen
 
Hi,

ich programmiere zur Zeit viel in C# und verwende dort auch diverse ORMs. Dort bin ich es gewöhnt zu den normalen (persistenten) Properties auch zusätzliche (berechnete) Properties zu programmieren.

Ein Beispiel wäre eine Rechnungsposition. In der Datenbank gibt es dann (minimalistisch dargestellt) die Felder:
Positionsnr
Menge
Einkaufspreis
AufschlagProzent

Zusätzlich würde ich also noch folgende Properties anlegen:
AufschlagAbsolut (berechnet sich aus Einkaufspreis / 100 * AufschlagProzent
Verkaufspreis (berechnet sich aus Einkaufspreis + AufschlagAbsolut)
Gesamtpreis (berechnet sich aus Verkaufspreis * Menge)

Bei den zusätzlichen Properties gibt es jetzt sowohl einen Getter als auch einen Setter.
Im Setter wird quasi rückwärtsgerechnet, sofern möglich... Beim Setter von Gesamtpreis wird z.B.
Code:
Verkaufspreis = neuerGesamtpreis / Menge
gerechnet...

Sinn und Zweck des Ganzen ist, dass man nur die nötigsten Werte abspeichert, die Logik dahinter nur einmal implementiert und es überall im Programm zuverlässig rechnet. Auch ist das Ganze sehr gut erweiterbar.

So mache ich das wie gesagt in C#.


Jetzt stelle ich mir die Frage, wie man sowas generell in Delphi macht. Da geht man ja eher den Weg über DataSets... Kann man da "virtuelle / berechnete" Spalten anlegen, die auch einen Setter implementieren können?
Bisher habe ich dazu nur ReadOnly-Spalten gesehen.

ORMs sind aufgrund der kaum brauchbaren LiveBindings ja noch nicht wirklich gut nutzbar in Delphi, oder?

Sir Rufo 22. Nov 2012 08:24

AW: Virtuelle Felder in DataSet erstellen
 
Die CalculatedFields sind ReadOnly da geht nix rein.

Ein ORM ist möglich, denn auch vor den LiveBindings konnte man schon Objekte in Tabellen darstellen.
Allerdings ist der LiveBindings Ansatz sehr charmant, wenn er denn praxistauglich wäre.

Morphie 22. Nov 2012 08:36

AW: Virtuelle Felder in DataSet erstellen
 
Wie ging das denn vor LiveBindings? DSharp?
Oder gibt es etwas anderes, was ich vielleicht verpasst habe?

Sir Rufo 22. Nov 2012 08:44

AW: Virtuelle Felder in DataSet erstellen
 
Zitat:

Zitat von Morphie (Beitrag 1192315)
Wie ging das denn vor LiveBindings? DSharp?
Oder gibt es etwas anderes, was ich vielleicht verpasst habe?

Presenter, ViewModel als Stichworte ;)

jaenicke 22. Nov 2012 11:21

AW: Virtuelle Felder in DataSet erstellen
 
Mit einem TClientDataSet (das wir mit dbExpress und dessen nativen Treibern für z.B. MySQL, MS SQL und Firebird nutzen) lassen sich z.B. TAggregateFields anlegen, wie gerade bei Coderage 7 gezeigt wurde:
http://www.youtube.com/watch?v=QaBNvuct35Q
Auch die sind aber nur Readonly AFAIK.

stahli 22. Nov 2012 11:48

AW: Virtuelle Felder in DataSet erstellen
 
Meiner bescheidenen Meinung nach werden hier einige Dinge durcheinander gewürfelt...

Ein ORM wird ja genutzt, um die Businesslogik mit Objekten zu realisieren (das ist für die Realisierung der Logik und Abläufe schön übersichtlich und vom Handling her einfach), die Daten aber in einer relationalen Datenbank zu halten (dies ermöglichst eine gute Strukturierung der Datenverwaltung incl. Joins usw).

Der ORM ist der Vermittler beider Welten.

Als Programmierer der Anwendung bezieht man sich im Grunde nur noch auf die Objekte. Wie die an ihre Daten kommen ist dabei nicht relevant.
(Natürlich muss das auch realisiert werden und es gibt verschiedene Ansätze und Tools dafür, aber für die eigentliche Anwendung spielt das keine Rolle.)

Wenn ich mit Objekten arbeite, kann ich beliebige Eigenschaften mit und ohne Setter und Getter definieren. Ich kann also (rein technisch gesehen) einen Setter set_Gesamtpreis einrichten, der intern irgendwelche Einzelpreise und Mengen zuweist.
Man müsste dann entscheiden, was in die Datenbank geschrieben wird... Nur der zugewiesene Gesamtpreis? Sicher nicht. Der Gesamtpreis und die berechneten Details? Sicher auch nicht. Also nur die Einzelpreise und Mengen. Der Gesamtpreis wird dann für die Rechnungslegung neu aus den Einzelposten berechnet.
Insofern reduziert sich set_Gesamtpreis auf eine Prozedur zur Festsetzung anderer Werte. Man könnte die Methode also auch als Prozedur regeln, die nicht als Setter fungiert (CalcDetailsForPrice).

Ein berechnetes Feld einer Datenmenge könnte das natürlich nicht. Dazu bräuchte man eine store procedure oder entsprechende update Statements.
Berechente Felder könnten nur einen Gesamtpreis aus Einzelpreis und Menge berechnen.

Das hat aber eigentlich nichts mit ORM oder LiveBindings zu tun.

Man konnte schon mit Delphi1 Klassen definieren, die ihre Feldwerte in Datenbanken schreiben oder daraus lesen. Das war etwas aufwendig, da man die Funktionalität für jedes Feld einzeln ausführen musste.
Mit der neuen RTTI ab Delphi 2010 kann man Klassen aber nun untersuchen und z.B. alle Propertys in einer Liste durchlaufen, Namen und Typ ermitteln und davon abhängig Daten zwischen Objekten und Tabellen übertragen.
Es können somit beliebige Objekte an eine solche Funktion übertragen werden, wobei die Funktion dann selbständig entscheidet, welche Daten wie übertragen werden können und müssen.
Später kann ich auch neue Klassen definieren und die entsprechenden Objekte zusätzlich übergeben, ohne mich um die Struktur der Objekte kümmen zu müssen (Stichwort Serialisierung).

Im Grunde erspart das aber "nur" Schreibarbeit, die man sonst für jede Klasse zusätzlich vornehmen müsste (ähnlich dem Wegfall eines Cast bei den Generics).

Das LiveBinding (bzw. DSharp oder odControls ;-)) ist noch eine andere Nummer. Hier geht es darum, die Daten im Formular zu präsentieren und dem Endnutzer eine Bearbeitung zu ermöglichen.
Klassisch würde man EditPerson.Text := MyPerson.Firstname schreiben und beim speichern die andere Richtung gehen.
Ein Databinding soll diese Arbeit (GlueCode) abnehmen. Man sagt einfach dem Edit (zur Designtime), welche Daten es anzeigen soll und ein Framework kümmert sich zur Laufzeit (mehr oder weniger gut), dass das auch so gemacht wird. Es überträgt also die Daten zwischen Objekt (oder DataSet) und GUI, ohne dass man dies im Quelltext selbst veranlassen muss.


Jetzt bin ich mal gespannt...

Morphie 22. Nov 2012 13:41

AW: Virtuelle Felder in DataSet erstellen
 
Also mir ist schon klar, wie ORMs funktionieren, ich nutze sie ja wie schon erwähnt selbst in C#.

Bei mir sieht das in etwa so aus:
Datenbank > aus dem ORM erstellte Klassen > ViewModels > Views
Wenn ich solche nicht persistenten Felder brauche, dann siehts so aus:
Datenbank > aus dem ORM erstellte Klassen > Von den ORM-Klassen geerbte Klassen mit den Erweiterungen > ViewModels > Views
In seltenen Fällen binde ich die Klassen auch direkt an die View.

Das ist in WPF alles ziemlich einfach über DataBinding umzusetzen...

Ich suchte jetzt in Delphi nach einer analogen oder alternativen Vorgehensweise.

Bisher habe ich in Delphi immer DataSet, DataSource usw. an irgendwelche Controls gebunden. Dort stehen mir dann ja exakt die persistenten Felder zur Verfügung, die ich auch in der Datenbank habe.
Wenn ich jetzt aber zusätzliche Funktionalität brauche, funktioniert das so einfach nicht mehr.

ORM hatte ich als alternative zu den DataSet / DataSource / Query / Table-Komponenten genannt. Damit ließe sich so etwas vielleicht analog zu WPF aufbauen. Doch dazu muss erst mal das DataBinding entsprechend funktionieren (was mit VisualBindings ja beabsichtigt wurde) Die Frage ist nur, ob das auch schon Praxistauglich ist...

stahli 22. Nov 2012 14:58

AW: Virtuelle Felder in DataSet erstellen
 
Ich habe früher das ECO-Framework als ORM angesehen und bin darauf hingewiesen worden, dass der ORM nur ein Teil davon ist (der eben die Verbindung der Objekteigenschaften zur Datenbank realsiert).

Du gehst offenbar auch von einem komplexeren Framework aus, dass es mit Delphi so m.E. nicht gibt. (Erfahrungen mit WPF habe ich nicht, daher kann ich das nicht genau nachvollziehen.)

Ich denke, meine Zusammenfassung beschreibt schon weitestgehend die Möglichkeiten, die Delphi bietet. Als ORM gibt es z.B. Aurelius, DORM und mORMot.
Die ermöglichen selbst aber noch keine Bindung an GUI-Controls oder Model-View-Definitionen.

Vielleicht hilft Dir das Video weiter, das ich mir sehr interessiert angesehen habe, wo ich aber im Nachhinein nicht wirklich den Aufwand/Nutzen abschätzen kann. Vielleicht ja demnächst beim zweiten Betrachten.

Eine gute Trennung von GUI + BL würde ich in Zukunft IMMER haben wollen, aber ob MVVM wirklich der sinnvollste Weg ist, davon bin ich (noch) nicht wirklich überzeugt.

Uwe Raabe 22. Nov 2012 16:20

AW: Virtuelle Felder in DataSet erstellen
 
Bei Aurelius (bei den anderen weiß ich es nicht) gibt es die Möglichkeit, die Klassen-Instanzen wieder über ein spezielles DataSet an datensensitive Controls zu hängen. Es ist dann völlig egal, wie die Properties realisiert sind und ob sie überhaupt mit Datenbankfeldern in Verbundung stehen. Damit ließe sich dein bisheriges Vorgehen wohl verwirklichen.

stahli 22. Nov 2012 23:54

AW: Virtuelle Felder in DataSet erstellen
 
@Morphie

Das Video von Olaf Monien geht wohl in die Richtung, wie Du arbeiten willst (ORM Aurelius und LiveBindings), geht aber leider auch nicht sehr in die Details (wie fügt der User Einträge hinzu und löscht sie, wie funktioniert die Nutzung im TMSFMXGRid wenn dort Indexsortierung und Gruppierung genutzt wird usw.).
Und GlueCode ist dann ja auch einiger nötig, also so ganz überzeugt mich das leider noch nicht.

Probleme mit dem LiveBinding gibt es viele. Ich habe mal um ein kleines Demoprojekt gebeten, um zu sehen, ob man außer fertige Daten zu präsentieren mit dem XE3, FM und LiveBinding überhaupt ein brauchbares und nutzbares Projekt realisieren kann: http://www.delphipraxis.net/171665-e...ml#post1191776
So ein Projekt müsste sich mit Delphi + Emba-Zubehör eigentlich in wenigen Minuten zusammen klicken lassen - aber halt auch so, dass es dann funktioniert.
Mal sehen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:26 Uhr.
Seite 1 von 2  1 2      

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