![]() |
Datenbank: MSSQL • Version: Egal • Zugriff über: LINQ
LINQ ORM Delphi (TMS / Devart)
Hallo zusammen,
In Kürze beginnen wir ein grösseres Projekt welches in Delphi umgesetzt werden muss. Von Visualstudio .Net bin ich mir mittlerweile einige Annehmlichkeiten gewohnt. Wie z.B. das SQL Gefrickel im Code zu vermeiden. Frage: Hat jemand Erfahrung mit einem ORM wie Devart, TMS Aurelius oder anderen und kann eine Empfehlung abgeben? |
AW: LINQ ORM Delphi (TMS / Devart)
Ich arbeite seit ein paar Jahren mit Aurelius. Erspart einem eine Menge SQL Gefummel und hilft so Fehler zu vermeiden. Allerdings sind die Datenmengen die da geschaufelt werden in der realen Welt nicht unerheblich. Dann muss man mit spezifischen Modellen arbeiten oder doch wieder manuell mit SQL arbeiten.
|
AW: LINQ ORM Delphi (TMS / Devart)
Hallöle...
Zitat:
Zum SQL Gefrickel: [Meine Lösung] Meine Statements liegen in einer Ordnerstruktur. Das bedeutet, die Statements sind ausführbar im Editor. Diese Struktur wird als Ressource einkompiliert. Das Interface holt sich die SQL aus der Ressource entsprechend des DBMS. In den Proceduren gibt es nur den Namensaufruf und die Zuordnung der Parameter...fertsch
Delphi-Quellcode:
function TBlubbDatabase.GetSQLByName(SQLName: string): string;
var SQLStream: TResourceStream; SQLStrings: TStringList; SQLStringsDecrypt: TStringList; begin Result := ''; SQLStrings := TStringList.Create; try SQLStringsDecrypt := TStringList.Create; try SQLStream := TResourceStream.Create(HInstance, SQLName, PWideChar(conDatabaseResourceGroupString)); try try SQLStrings.LoadFromStream(SQLStream); SQLStringsDecrypt.Text := TBlubbToolsCrypt.Decrypt(SQLStrings.Text, conKey); //Verschlüsselung wenn nötig SQLStringsDecrypt.Delete(0); // Kommentar entfernen Result := SQLStringsDecrypt.Text; except Result := ''; end; finally SQLStream.Free; end; finally SQLStringsDecrypt.Free; end; finally SQLStrings.Free; end; end;
Delphi-Quellcode:
procedure TBlubbDatabase.FillList(List: TBlubbFieldList; TableName: string);
var I: Integer; Qry: TFDQuery; Field: TBlubbField; begin Qry := CreateQuery; try Qry.SQL.Text := Format(GetSQLByName('BLUBB_TABLE_FIELDLIST'), [TableName]); Qry.Open; if not Qry.Eof then begin List.Clear; for I := 0 to Qry.Fields.Count - 1 do begin Field := TBlubbField.Create; Field.FieldIndex := I; Field.FieldName := Qry.Fields[I].FieldName; Field.Fieldype := Qry.Fields[I].DataType; List.Add(Field); end; end; finally Qry.Free; end; end; |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
Es kann so einfach sein. Code First oder Database First. Und dann alles per LINQ. Ist schon eine andere Nummer bezüglich Übersichtlichkeit und Anwendung. |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Beim Aurelius musst Du aufpassen, ob Du datenbank transaktionen brauchst. Das hat da kein gutes Modell. Ich hatte eine längere Diskussion mit Wagner Landgraf (dem Programmierer von Aurelius) und hab ihm erklärt dass sein augenblickliches Modell es nicht zulässt, 2 Instanzen vom gleichen Object zu erstellen, jedes mit eigenem ObjectManager und dann getrennt commit oder rollback zu machen. Bei Aurelius (Stand Version 3.3) ist es so, dass es global nur eine Transaction gibt (ich nutze UniDAC), die von der TUniConnection selbst kommt. Das heisst dann aber auch, dass wenn ich Commit in einem Fenster mache, er auch die Daten von Fenster 2 committed.
Seine Lösung war eine neue DbVerbindung für jedes Fenser. :roll: Also ein kleieres Projekt machte ich damit, das geht sehr gut, dort nutze ich aber nur sehr begrenzt und sequentiell das Schreiben der Daten in die Db. |
AW: LINQ ORM Delphi (TMS / Devart)
Um mal noch ein interessantes Projekt zu nennen: mORMot - Super Doku, allerdings eine gewissen Einarbeitungszeit ist schon nötig.
...:cat:... |
AW: LINQ ORM Delphi (TMS / Devart)
Oder MarshMallow (nun Teil von Spring4D).
|
AW: LINQ ORM Delphi (TMS / Devart)
Ja, mOrmot hat eine steile Lernkurve. Dafür ist es aber auch wirklich umfassend. Leider läuft auch die interne Kommunikation C/S mit JSON. Daher eher für echte Multi-Tier Anwendungen geeignet. Vorteil: Es ist zu jeder Delphi-Version kompatibel. Nachteil: Es ist zu jeder Delphi-Version kompatibel.
Basiert daher zwingend auf Vererbung und eigenen Datentypen. |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
...:cat:... |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
- Daten holen: ObjectManager nach EntityObject/en fragen. Aus den EntityObject/en das BusinessObject erzeugen ObjectManager wegwerfen. Mit dem BusinessObject arbeiten. - Daten schreiben: ObjectManager nach EntityObject/en fragen. EntityObject/e mit BusinessObject aktualisieren ObjectManager Änderungen speichern ObjectManager wegwerfen. Jetzt mal so nachzählen: Wieviele ObjectManager haben wir so bei 50 MDI-Formularen geöffnet? IdR 0 (in Worten null) nur wenn etwas geladen oder gespeichert wird, dann sind die da und weil es für jede Aktion Lesen oder Schreiben einen eigenen ObjectManager gibt, kommen die sich auch nicht mit den Transaktionen ins Gehege. |
AW: LINQ ORM Delphi (TMS / Devart)
Das problem ist ja aber, dass ich nicht eine komplett neue Anwendung schreibe, sondern schon 700.000 Zeilen Code habe ;) Und das ist alles basierend auf einem transaktionellen modell, wo die einzelnen Fenstern in einer eigenen Transaktion laufen.
Das umzubauen ist auch ziemlich heftig :p |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
Es ist allerdings etwas unfair wenn du hier die Schuld auf Aurelius schiebst, denn so hört sich deine Aussage dazu an. |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
Ist man da mit einer Interbase/Firebird Datenbank verbunden, geht es garnicht andrs als dass man über einen langen Zeitraum die Transaktion offen hat, denn sowie man sie schliesst, schliessen die Table/Queries auch. Zitat:
Nichts desto trotz besteht die Gefahr die Kritik dass es nicht sauber gekapselt ist und man unter Umständen Sachen committed, die man noch garnicht schreiben will. |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
Zitat:
![]() Nur weil Emba das mit dem Rapid Application Development da etwas losgetreten hat, wird es nicht richtig. Man kann damit schnell mal was hinklatschen, aber dadurch hast du auch schon die Trennung zwischen UI, Logik und Persistenz nicht eingehalten. Also gleich mehrere Fehler auf einmal. Die Rache kommt irgendwann später, aber sie kommt. Natürlich funktioniert so ein Ansatz, aber er klebt halt wie Pech an deinen Händen. |
AW: LINQ ORM Delphi (TMS / Devart)
Da kommen wir wieder zu dem zurück, wo ich sagte, dass die Anwendung ja schon da ist, schon seit Delphi 2 und ich bezweifle, das diese ORM Modelle damals schon gang und gäbe waren.
Nichts desto trotz sehe ich den ObjectManager eigentlich als meine Datenhalter an, der sich drum kümmert, meine aus der Datenbank geladenen Daten im Speicher zu halten. Es würde ja auch nicht viel Sinn machen wenn : Aurelius lädt Daten aus der DB diese werden in Entities abgelegt Ich lade die Entities dann in eigene Objecte, damt ich den ObjectManager freigeben kann Ich arbeite dann mit meinen Objekten und wenn ich Änderungen schreiben will, lade ich wieder die Entities aus der DB, ändere sie und schreibe sie zurück. Da ist für mich 1 Kappe zuviel. Die Entities sind ja direkt mit deiner GUI verbindbar und werden auf zuruf erst in die DB geschrieben (ObjectManager.Flush;). Solange ich dies nicht aufrufe sollte es möglich sein, an den objekten rumzufummeln, bis ich schwarz werde, oder ? |
AW: LINQ ORM Delphi (TMS / Devart)
@MyRealName
Doch, genau so macht man das mit den Entitäten. Denn diese Entitäten sind die Datenbank-Tabellen als Klassen dargestellt. Und mit der Tabellen-Struktur löst man das Problem der Speicherung. Punkt. Das Business-Objekt kann dabei schon wieder ganz anders aussehen. Kleines Beispiel: Wir haben einen Blog-Eintrag und jeder Benutzer diesen Beitrag bewerten. Das Business-Objekt sieht so aus
Code:
Die Entity-Objekte (Tabellen) dazu sehen aber etwas anders aus
BlogEntry
- Id - Titel - Body - Rate (Bewertung des Benutzers)
Code:
denn wir wollen in den Tabellen die Bewertung von n Benutzern speichern können.
Blog
- Id - Titel - Body BlogUserRate - BlogId - UserId - Rate Wenn einem da also auch nichts auf die Füße fallen soll, dann trennt man ganz brav zwischen Business-Layer und Daten-Layer. Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Aber dein Modell ha ja auch nur 3 layer :
1. Datenbank mit Tabellen 2. Entities, die die Daten halten 3. GUI Was du aber vorher geschrieben hast (zumindest wie ich es verstehe) war : 1. Datenbank 2. Entities 3. Meine Business Logic Objekte 4. GUI Welches ist es denn ? |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
![]() |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
![]() Generell finde ich aber, dass man die beiden Frameworks sehr gut miteinander kombinieren kann. :thumb: Bis jetzt war das größte Problem nur das Nullable. |
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
AW: LINQ ORM Delphi (TMS / Devart)
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:10 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