![]() |
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:
gerechnet...
Verkaufspreis = neuerGesamtpreis / Menge
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? |
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. |
AW: Virtuelle Felder in DataSet erstellen
Wie ging das denn vor LiveBindings? DSharp?
Oder gibt es etwas anderes, was ich vielleicht verpasst habe? |
AW: Virtuelle Felder in DataSet erstellen
Zitat:
|
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:
![]() Auch die sind aber nur Readonly AFAIK. |
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... |
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... |
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 ![]() 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. |
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.
|
AW: Virtuelle Felder in DataSet erstellen
@Morphie
Das ![]() 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: ![]() 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 10:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz