Laden...

typisiertes Dataset erweitern

Erstellt von ErfinderDesRades vor 13 Jahren Letzter Beitrag vor 12 Jahren 6.641 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 13 Jahren
typisiertes Dataset erweitern

Man kann in der partialen Klasse im Code-Behind eines typisierten Datasets prinzipiell beliebigen Geschäftscode hinterlegen. Das ist ganz lustig, ich hab hier zB. was gemacht, wo die DataRows als ZeichenObjekte funktionieren, die selbst wissen, wie sie sich in ein Graphics-Objekt zu zeichnen haben.
Da taucht leider das Problem auf, dass diese Datarows sich nicht mehr ohne weiteres abspeichern können, weil Point, Rectangle und so Sachen sind zwar als DatenTyp einer DatenSpalte zulässig, können aber nicht abgespeichert werden, weil Dataset.WriteXml() nur Xml-serialisierbare Typen unterstützt, und DB-Provider noch weniger - ich glaub, nur die sog. "primitives" : Zahlen, Datum, Text, und ansonsten behilft man sich mit Blobs - also Byte-Arrays, die man je nachdem entsprechend auslesen muß (zB mit Bitmap funzt das so).

Also habe ich einen DatasetSaver gebastelt, der ein wesentlich breiteres Spektrum an Datentypen verarbeitet. Prinzipiell gleich wie Dataset.WriteXml() schreibt er das Dataset als TextFile auf Platte. Nur verwendet er nicht Xml-serialisierung, sondern 2 verschiedene Konvertierungs-Methoden:*Wenn ein TypConverter für den Typ vorgesehen ist, der den Typ nach byte[] oder string konvertieren kann, natürlich vorrangig diesen. Vorteil: Eine TypConverter-Konvertierung nach String ist von Menschen lesbar. Schon damit sind die Möglichkeiten erheblich erweitert, zB. können jetzt problemlos auch Enums als Spaltentyp hergenommen werden, und Point, Rectangle und Konsorten sind damit auch abgedeckt. *ansonsten produziert er einen Blob, der in einen Base64String konvertiert wird. Letzterer ist zwar nicht lesbar, aber das Blobben kann mit allen(!) reinen WertTypen durchgeführt werden (also die keine VerweisTypen enthalten), und auch mit Arrays von WertTypen, sogar mehrdimensionalen.

Nicht konvertiert werden können Klassen (VerweisTypen), für die sich kein TypConverter nach Byte[] oder String findet.

Für das TextFile habe ich mir ein eigenes File-Format ausgedacht, ähnlich CSV, nur noch primitiver, und(!): es kann natürlich mehrere Tabellen in einer Datei aufnehmen.
Interessanterweise erweist sich mein Compact-Format als besser lesbar als das Xml, welches durch Dataset.WriteXml() produziert wird. Ich zeige mal drei Tabellen _desselben _Datasets in Gegenüberstellung:


[xml]<?xml version="1.0" standalone="yes"?>
<GrKassDts xmlns="http://tempuri.org/GrKassDts.xsd">
  <Settings>
    <AdminPassword>admin</AdminPassword>
    <Saldo0>450</Saldo0>
    <SumKasse>264.8711</SumKasse>
    <SumBelege>264.87</SumBelege>
    <SumAuffuell>170</SumAuffuell>
    <Saldo1>355.1289</Saldo1>
    <SettingsID>0</SettingsID>
    <GruppeName>Sb75</GruppeName>
    <SumAktVorschuss>85.13</SumAktVorschuss>
    <Saldo2>269.9989</Saldo2>
    <SumStueck>342,40</SumStueck>
  </Settings>
  <Betreuer>
    <BetreuerID>-2</BetreuerID>
    <BetreuerName>Ahlers</BetreuerName>
    <VorschussUebertrag>0</VorschussUebertrag>
    <SumVorschuss>250</SumVorschuss>
    <SumBelege>106.43</SumBelege>
    <SettingsID>0</SettingsID>
    <AktVorschuss>143.57</AktVorschuss>
  </Betreuer>
  <Betreuer>
    <BetreuerID>-3</BetreuerID>
    <BetreuerName>Bhugon</BetreuerName>
    <VorschussUebertrag>0</VorschussUebertrag>
    <SumVorschuss>100</SumVorschuss>
    <SumBelege>115.44</SumBelege>
    <SettingsID>0</SettingsID>
    <AktVorschuss>-15.44</AktVorschuss>
  </Betreuer>
  <Betreuer>
    <BetreuerID>-4</BetreuerID>
    <BetreuerName>Bhieler</BetreuerName>
    <VorschussUebertrag>0</VorschussUebertrag>
    <SumVorschuss>0</SumVorschuss>
    <SumBelege>43</SumBelege>
    <SettingsID>0</SettingsID>
    <AktVorschuss>-43</AktVorschuss>
  </Betreuer>
  <Betreuer>
    <BetreuerID>-5</BetreuerID>
    <BetreuerName>Janssen</BetreuerName>
    <VorschussUebertrag>0</VorschussUebertrag>
    <SumVorschuss>0</SumVorschuss>
    <SumBelege>0</SumBelege>
    <SettingsID>0</SettingsID>
    <AktVorschuss>0</AktVorschuss>
  </Betreuer>
  <Vorschuss>
    <VorschussID>-1</VorschussID>
    <Datum>2010-11-20T00:00:00+01:00</Datum>
    <Betrag>100</Betrag>
    <BetreuerID>-2</BetreuerID>
  </Vorschuss>
  <Vorschuss>
    <VorschussID>-2</VorschussID>
    <Datum>2010-11-30T00:00:00+01:00</Datum>
    <Betrag>150</Betrag>
    <BetreuerID>-2</BetreuerID>
  </Vorschuss>
  <Vorschuss>
    <VorschussID>-5</VorschussID>
    <Datum>2010-12-12T00:00:00+01:00</Datum>
    <Betrag>100</Betrag>
    <BetreuerID>-3</BetreuerID>
  </Vorschuss>[/xml]


[pre]°Settings: AdminPassword, Saldo0, SettingsID, GruppeName
°admin°450°0°Sb75

°Betreuer: BetreuerID, BetreuerName, VorschussUebertrag, SettingsID
°-2°Ahlers°0°0
°-3°Bhugon°0°0
°-4°Bhieler°0°0
°-5°Janssen°0°0

°Vorschuss: VorschussID, Datum, Betrag, BetreuerID
°-1°2010-11-20°100°-2
°-2°2010-11-30°150°-2
°-5°2010-12-12°100°-3
[/pre]

Man bekommt eine Vorstellung, warum ich es "Compact-Format" nenne 😉?
Ein Konzept des Compact-Formats ist nämlich, Meta-Informationen nicht mit in die Datei zu nehmen.
Denn diese Information ist ja sowohl im Sender als auch im Empfänger der Daten vorhanden. Ich meine, ein "GrKassDts"-Dataset kennt doch seine Tabellen und Spaltennamen - wozu muß es die noch einmal aus dem DatenFile auslesen? Ein falsches DatenFile kann gar nicht untergeschoben werden, denn wenn eine Tabelle die falsche Spalten-Anzahl aufweist, oder wenn ein Eintrag nicht in den erwarteten Typ konvertiert werden kann, scheitert der Lese-Vorgang ebenso, wie er beim Einlesen einer fehlerhaften Xml-Datei scheitern würde.
Die vom DatasetSaver erzeugten Tabellenköpfe dienen v.a. der Lesbarkeit - bis auf das 1.Zeichen werden sie nicht ausgewertet.
Jo - und ist doch schön zu erkennen: Alle Betreuer hängen am selben Settings-Datensatz. Ahlers hat 2 Vorschüsse erhalten, Bhugon einen, die anderen keinen.

Die Sample-Solution - "Collage-Builder"
Man kann Text-Objekte anlegen und Bild-Objekte. Man kann Collagen anlegen, und jeder Collage ausgewählte Texte und Bilder zufügen. Die Texte und Bilder sind auf einem "Canvas"-Control verschiebbar, das jeweils angewählte Objekt wird in den Vordergrund geholt.
Das ist erstmal alles, ein Dragging der Objekt-Größen oder ein Drehen habe ich nicht implementiert, ebensowenig wie den Export in ein JPG-File.

Ich will ja nur demonstrieren, wie man typisierte DataRows mit beliebiger Funktionalität erweitert, und es bleiben trotzdem DataRows: also eingebunden in ein relationales Datenmodell (anders wäre das Auswählen und Zusammenstellen der Text- und Bild-Objekte nicht machbar), und - wups! - den ganzen Kram auf Platte geschrieben.

Schlagworte: typisiert, dataset, persistenz, abspeichern

Der frühe Apfel fängt den Wurm.

ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 12 Jahren

Hier mal ein Bild vonne Sample-App.

Von bisher 2 Kompositionen ist "composition2" ausgewählt - die kombiniert ein Image mit 2 Texten.
Die Abmaße der Kompositions-Elemente sind angezeigt, und updaten sich per Databinding, wenn man ein Element verschiebt.

Das ist schonmal für sich eine hübsche Spielerei: ZeichenObjekte, verwaltet in einem relationalen Datenmodell.

DatasetSaver-spezifisch ist jedoch, dass die Abmaße nicht als 4 int-Properties im Dataset gehalten werden, sondern die "Composition"-DataTable enthält tatsächlich eine DataColumn "Bounds" vom Typ Rectangle.

Und die "Text"-DataTable (hier nicht zu sehen, da auf der "Resources"-Tabpage) enthält eine DataColumn vom Typ Font.

Beide DataColumns machen beim Laden und Speichern des Datasets kein Problem.

Der frühe Apfel fängt den Wurm.