Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Nullable VS Nullable (https://www.delphipraxis.net/199250-nullable-vs-nullable.html)

WiPhi 9. Jan 2019 09:42

Delphi-Version: 10.2 Tokyo

Nullable VS Nullable
 
Hallo liebe DPler,

ich stehe zur Zeit vor einem Problem welches Nullables aus zwei Frameworks betrifft: Spring4D Nullables vs Aurelius Nullables.

Zur Zeit verwende ich die Aurelis (ORM) Bibliothek und dessen Nullables zur Definition von den Datenstrukturen.
Jetzt habe ich mich in die Spring4D eingearbeitet und dort auch die Nullables entdeckt. Natürlich sind diese anders deklariert als die aus Aurelius.

Meine erste Idee war, ich verwende strikt nur einen Nullable-Typen und zwar den aus Spring. Mit diesem kommt Aurelius jedoch nicht klar, da dieser zwar erkennt das es sich um einen Nullable handelt, ihm jedoch die Informationen aus Aurelius fehlen (war auch zu erwarten).

Wiederrum könnte ich den Aurelius-Nullable überall verwenden. Jedoch wird das ganze problematisch sobald ich die Unit Spring einbinde, in welcher u.A. auch der Nullable für Spring deklariert ist. Das Typen-Chaos will ich unbedingt vermeiden!

Vielleicht hat der ein oder andere eine Idee wie ich beide Typen (oder besser gesagt beide Frameworks mit gleichnamigen Typen) miteinander verwenden kann? :roll:

Schokohase 9. Jan 2019 09:50

AW: Nullable VS Nullable
 
Wenn du SoC berücksichtigst, dann ist es kein Problem.

Du hast ein Domain-Model und für die Speicherung mit dem Aurelius-ORM entsprechende Entity-Models. Zum Speichern erzeugst du dir aus dem Domain-Model das Entity-Model bzw. zum Lesen erzeugst du dir aus dem Entity-Model das Domain-Model.

hoika 9. Jan 2019 10:55

AW: Nullable VS Nullable
 
Hallo,
Zitat:

Jedoch wird das ganze problematisch sobald ich die Unit Spring einbinde, in welcher u.A. auch der Nullable für Spring deklariert ist. Das Typen-Chaos will ich unbedingt vermeiden!
Binde die Aurelius-Nullable-Unit immer als letzte Unit ein.
Oder definier dir einen eigenen Nullable-Type, der vom Aurelis-Typ abgeleitet ist:
type TMyNullable = Aurelius.Nullable.

WiPhi 10. Jan 2019 07:49

AW: Nullable VS Nullable
 
Ich danke euch für die Anregungen.
Derzeit habe ich es so gelöst wie hoika es vorgeschlagen hat: Die Aurelis Unit als letztes einbinden. Ich prüfe demnächst noch, ob ich es sich lohnt den Aurelis-Typen durch meinen eigenen zu ersetzen.

Das Problem besteht wirklich darin, dass in der Spring-Unit alle Basis-Typen von Spring4D deklariert sind.

Z.B.: Ich benutze den Nullable-Spring nicht, möchte aber dennoch den TValue-Helper verwenden. (Konkret die Fähigkeit des Helpers um Werte zu konvertieren.)

Delphi-Quellcode:
uses
  Spring;
// <snip>
procedure Foo;
var
  x: String
  Value: TValue
begin
  Value := 20;
  x := Value.ToType<String>;
end;
Möchte ich jetzt aber eine Nullable-Konvertierung durchführen, registriere ich zuerst Aurelis-Nullable Konverter:
Delphi-Quellcode:
uses
  Spring.ValueConverters,
  Aurelius.Nullable;

// <snip>
TValueConverterFactory.RegisterConverter([SaemtlicheTypen], TypeInfo(Aurelius.Nullable<EntsprechenderTyp>), TTypeToNullableConverter); // und natürlich die Gegenrichtung
Besonders schön ist das die Klasse TTypeToNullableConverter nicht von mir, sondern auch aus Spring stammt und augenscheinlich mit dem Aurelius-Nullable klar kommt.

Anschließend kann ich Aurelius.Nullable-Konvertierungen durchführen:

Delphi-Quellcode:
uses
  Spring,
  Aurelius.Nullable;
// <snip>
procedure Foo;
var
  x: Nullable<String>
  Value: TValue;
begin
  Value := 20;
  x := Value.ToType<Nullable<String>>;
end;
Vielleicht hat jemand noch eine andere Idee, anonsten kann ich (und auch zukünftige Entwickler des Projekts) denk ich damit umgehen.

freimatz 10. Jan 2019 07:53

AW: Nullable VS Nullable
 
Zitat:

Zitat von WiPhi (Beitrag 1423009)
Das Problem besteht wirklich darin, dass in der Spring-Unit alle Basis-Typen von Spring4D deklariert sind.
...
Vielleicht hat jemand noch eine andere Idee, anonsten kann ich (und auch zukünftige Entwickler des Projekts) denk ich damit umgehen.

Bei Spring4D vorstellig werden, sie mögen doch bitte eine eigene unit für die Nullable machen?

mkinzler 10. Jan 2019 09:46

AW: Nullable VS Nullable
 
Spring4D beinhaltet auch ein ORM (MarshMallow)

TiGü 10. Jan 2019 10:19

AW: Nullable VS Nullable
 
Ohne beide Typen je unter die Finger bekommen zu haben, aber kann man nicht je einen record helper schreiben, der zwischen den verschiedenen Typen automatisch konvertiert bei Zuweisung?

WiPhi 10. Jan 2019 12:01

AW: Nullable VS Nullable
 
Zitat:

Zitat von mkinzler (Beitrag 1423024)
Spring4D beinhaltet auch ein ORM (MarshMallow)

Hatte ich mir als aller erstes ORM angeschaut, jedoch fehlen mir darin wichtige Funktionen. Vor allem verbundene Primary Keys zu verwenden. Deswegen bin ich zu Aurelius gewechselt.

Zitat:

Zitat von TiGü (Beitrag 1423029)
Ohne beide Typen je unter die Finger bekommen zu haben, aber kann man nicht je einen record helper schreiben, der zwischen den verschiedenen Typen automatisch konvertiert bei Zuweisung?

Das wäre meine Traumlösung mittels Implict Zuweisungen, jedoch lt. Delphi Hilfe http://docwiki.embarcadero.com/RADSt...oading_(Delphi) Note: Class and record helpers do not support operator overloading.

Da bin ich schon an der Deklaration gescheitert. Spring4D hat das irgendwie hinbekommen (s. TValue Helper), jedoch kam ich noch nicht dazu mir das genauer anzuschauen. Ehrlich gesagt ist das mit den Operanden-Überladen noch ziemliches Neuland für mich.
Wie müsste das dann ungefähr aussehen?

Danke für eure Anregungen :thumb:

Schokohase 10. Jan 2019 12:38

AW: Nullable VS Nullable
 
Ich möchte nochmals darauf hinweisen, dass gerade hier bei der Einhaltung von SoC dieses Problem nicht wirklich existiert, bzw. an nur einer überschaubaren Stelle auftritt.

Die Entity-Klassen für Aurelius (oder jedes andere ORM-Framework) spiegeln 1:1 die SQL-Tabellen wieder und nur in den eher zufällig seltenen Fällen auch Anwendungs-Klassen.

Beispiel:
Delphi-Quellcode:
// Domain-Model
TAddress = record
  Street: string;
  PostalCode: string;
  City: string;
end;

TContact = record
  Id : Integer;
  Firstname: string;
  Lastname: string;
  Addresses: TArray<TAddress>;
end;
und nun die ORM-Klassen, damit das auch in eine Datenbank rein kann
Delphi-Quellcode:
// Entity-Model
TContact = class
  property Id: Integer;
  // Concurrency-Conflicts-Detection
  property Version: Integer;
  property Firstname: string;
  property Lastname: string;
end;

TContactAddress = class
  property ContactId: Integer;
  property Position: Integer;
  property Street: string;
  property PostalCode: string;
  property City: string;
end;
Obwohl sich in beiden Informationen zu einem Kontakt befinden gibt es dennoch unterschiedliche Ansprüche an das Layout. Um das Addresses-Array auch exakt wiederherstellen zu können benötigt man zusätzlich auch die Position. Oder zum Erkennen von Concurrency-Conflicts die Version. Damit will man sich aber auf der Anwendungsebene nicht herumschlagen, zumal dieses (Position) auch wiederum der relationalen Datenbank geschuldet ist. Bei einer NoSQL-Datenbank könnte man darauf (Position) wiederum verzichten, denn dort wird auch die Reihenfolge der Adressen gespeichert.

TiGü 10. Jan 2019 12:50

AW: Nullable VS Nullable
 
Zitat:

Zitat von WiPhi (Beitrag 1423037)
Zitat:

Zitat von TiGü (Beitrag 1423029)
Ohne beide Typen je unter die Finger bekommen zu haben, aber kann man nicht je einen record helper schreiben, der zwischen den verschiedenen Typen automatisch konvertiert bei Zuweisung?

Das wäre meine Traumlösung mittels Implict Zuweisungen, jedoch lt. Delphi Hilfe http://docwiki.embarcadero.com/RADSt...oading_(Delphi) Note: Class and record helpers do not support operator overloading.

Da bin ich schon an der Deklaration gescheitert. Spring4D hat das irgendwie hinbekommen (s. TValue Helper), jedoch kam ich noch nicht dazu mir das genauer anzuschauen. Ehrlich gesagt ist das mit den Operanden-Überladen noch ziemliches Neuland für mich.
Wie müsste das dann ungefähr aussehen?

Hm, so richtig will das nicht mit den generischen Operator für record helper.
Höchstens so ein "stumpfer" Ansatz mit Konvertierungsfunktionen scheint zu kompilieren:

Delphi-Quellcode:
unit Spring.Helper;

interface

uses
  Spring;

type

  TAureliusNullableType<T> = record

  end;

//  TSpringNullable = Spring.Nullable<T>;
////
//  NullableHelper<T> = record helper for TSpringNullable
//  public
//    class operator Implicit(const value: TAureliusNullableType<T>): Spring.Nullable<T>;
//  end;

  TNullableConverter<T> = record
    class function ConvertSpring(const AureliusNullable: TAureliusNullableType<T>): Spring.Nullable<T>; static;
    class function ConvertAurelius(const SpringNullable: Spring.Nullable<T>): TAureliusNullableType<T>; static;
  end;



implementation

{ NullableHelper }

//class operator NullableHelper.Implicit(const value: TAureliusNullableType): Spring.Nullable<T>;
//begin
//end;

{ THelper<T> }

class function TNullableConverter<T>.ConvertAurelius(const SpringNullable: Spring.Nullable<T>): TAureliusNullableType<T>;
begin
  // Hausaufgabe
end;

class function TNullableConverter<T>.ConvertSpring(const AureliusNullable: TAureliusNullableType<T>): Spring.Nullable<T>;
begin
  // Hausaufgabe
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf