Seit einer ganzen weile arbeite ich an meinem eigenen O/R Mapper.
Ich versuche eine saubere, leicht-verständliche und stabile Bibliothek zu schaffen.
Leider habe ich nimanden, mit dem ich das Design und auch die konkrete Implementation besprechen/reviewen kann.
Folglich suche ich jemanden, der sich meinen Code und Design widmet, kritisch hinschaut und mir vielleicht auch Ideen für neue Features hat.
(( Rand Info: ca. 300KB *.cs-Dateien ))
Wenn es jemand versuchen will schicke ich gerne das Projekt und würde auch gerne direkt reden, da ich (wie zu erwarten) keine Zeit für eine ausreichende Doku habe (Inline und XML-Doku ist vorhanden).
Schon mal Danke an jeden, der mein Anliegen liest.
ich denke, dass es nicht jedermanns Sache ist, sich durch 300K Code zu wühlen, zumal es einerseits schwierig ist, aus 300K wenig dokumentiertem Code das Design herauszufinden und man anderseits für die Beurteilung der konkreten Implementierung vermutlich nicht mehr als ein oder zwei CS-Dateien braucht.
Warum beschreibst du nicht in "Rund um die Programmierung" das Design mit einer Bitte um Feedback?
Für die Codeanalyse kannst du einzelne CS-Dateien in Absprache immer noch an Interessiere verschicken.
Ich halte das von mir beschriebene Vorgehen für erfolgversprechender.
Original von herbivore
.. ich denke, dass es nicht jedermanns Sache ist, sich durch 300K Code zu wühlen ...
Deshalb hab ich es auch hingeschrieben und auch nicht gleich den Code mit dazu geklatscht. Mir ist vollkommen klar, das man damit so gut wie nichts anfangen kann.
Wenn ich mal genügend Zeit finde, werde ich das Design aufschreiben/aufzeichnen und deinem Vorschlag folgen. Sollte sich jemand ehr melden, würde ich das Design erst mal mit ihm/ihr besprechen, da ich befürchte nicht all zu bald zum Dokumentieren zu kommen. ( Cheff drängelt und verteilt ständig noch mehr Aufgaben )
Mein O/R Mapper ist endlich qualitätsgesichert worden und nun in der Version 2.0.0.29 verfügbar. Eine Anleitung lässt leider immernoch auf sich warten, aber die XML-Dokumentation (Geleben Tooltips im VS) sind mit dabei.
ich kann Deine Absicht nicht erkennen. Du möchtest von der Community Feedback zu einem OR-Mapping-Tool, welches Du entwickelt hast. Aber Du willst bzw. darfst den Quellcode nicht rausrücken. Wie soll das funktionieren?
Wenn Du den Quellcode nicht veröffentlichen möchtest, dann solltest Du wenigstens das Konzept Deines OR-Mappers erklären. Was unterscheidet Deinen OR-Mapper von den vielen anderen OR-Mappern? Welche Features haben den Aufwand gelohnt, überhaupt einen eigenen OR-Mapper zu entwickeln? Was hat Dein OR-Mapper, was die anderen (z.B. NHibernate) nicht haben?
Bisher wissen wir nur, dass es keine Doku gibt und es 300 KB an CS-Dateien sind. Das weckt nicht gerade das Interesse an diesem Projekt.
Den Quellcode darf und werde ich veröffentlichen. Ich möchte nur noch nicht, da eben keine Doku vorhanden ist. Ich möchte gerne eine vollständige Komponente rausgeben.
Ich habe keine Ahnung, was meinen O/R Mapper von allen anderen Unterscheidet. Ich habe den O/R Mapper eigentlich aus Übungszwecken und zum Spass angefangen. Und da in meiner Firma noch FoxPro-Style programmiert wurde, konnte der OO-Ansatz und mein Mapper schnell Punkten und wurde übernommen.
Ich würde jetzt gerne 3h Zeit nehmen und eine Doku zu meinem O/R Mapper schreiben, nur leider muss ich arbeiten. Ich beiss mir ja schon selbst in den Hintern, weil immer noch keine Dokumentation (außer XML-Doku) existiert.
Rainbirds Fragen haben mich nicht los gelassen und so hab ich mir ein paar mehr Gedanken gemacht.
Was ich mit meinem O/R Mapper erreichen will/wollte:
Nur noch eine Klasse schreiben
Mein Haupt ziel ist es, dass ein Entwickler nur noch eine einzige Klasse schreiben muss, um eine vollwertige Anwendung zu entwikeln. Es werden "nurnoch" Mappinginformationen und die Logik hinterlegt (in der Klasse, nicht irgend wo). Datenschicht und UI sollten nicht mehr beachtet werden müssen.
Das Ziel ist noch nicht erreicht, der Entwikler muss immer noch die Datenbank und Tabellen anlegen und die generische UI ist auch noch ehr eine Betaversion. Naja, das Mappen und die Erzeugung der SQL-Commands (SELECT, INSERT, UPDATE und DELETE) ist schon fertig.
Weniger Datenbankzugriffe
Ein weiteres sehr wichtiges Ziel war es, die Datenbankzugriffe zu reduzieren. Durch das definieren von Chachespeichern (≤Klasse) lassen sich Gültigkeitsbereiche für persistente Objekte definieren. Innerhalb des Gültigkeitsbereiches werden die Objekte nicht erneut aus der Datenbank geladen, sondern die bestehenden Objekte weiter verwendet (was den schönen Nebeneffekt hat, dass object.ReferenzEquals auch true zurück gibt, wenn es sich um den gleichen Datensatz handelt). Und dabei bleibt die Steuerung der Gültigkeitsbereiche/Chachespeicher beim Entwikler und er kann bestimmen, wann neue Objete geladen werden.
Datenbank-Unabhänig
Ich will mich nicht mit fremden Federn schmücken. Wir hatten schon eine Datenbank-Klasse, die Orakle und MsSQL ansprechen konnte. Mein O/R Mapper verwendet intern diese Klasse. Nun sorgt aber der O/R Mapper dafür, dass alle Commands nur standard ANSI SQL enthalten und so auf "jeder" Datenbank ausgeführt werden können. (omg, ich erinnere mich nocht, dass unsere Anwendung nicht auf Orakle lief, weil unser Kollege TOP verwendet hat!)
alle OO Möglichkeiten (und absolute OO)
Ein mir persönlich sehr wichtiges Ziel ist es, dass man durch den Einsatz (m)eines O/R Mappers nicht eingeschränkt wird. Es sollte möglich sein, alle OOP-Konstrukte (Patterns, Vererbung, Generiks, Konstruktoren, etc.) und alle C#-Konstrukte zu verwenden. Und der Mapper selbst sollte gegen keine "Regeln" der OO verstossen (Kapselung, etc.).
Das ganze ist mir auch geglückt, mit einer Ausnahme im Moment müssen alle persistenten Klassen von Aisys.AisysObject erben (aber ich hoffe dies in Version 2.1.0.x zu beheben).
einheitliche und einfache Syntax
Später (nach Version 0.8.0.x) kamm noch hinzu, dass die Verwendung des O/R Mappers und der persistenten Klassen immer gleich ist.
Naja, der O/R Mapper erlaubt diverse verwendungen, wurde aber für einen Code-Stiel optimiert. Schon wiedersprechen sich die Ziele *lach*.
Erweiterbarkeit/Anpassbarkeit
Mein O/R Mapper selbst und auch die persistenten Klassen sollten möglichst einfach angepasst werden können und zwar OHNE Assemblies zu ändern.
Das hatte dann natürlich nicht mehr viel mit einem O/R Mapper zu tun, weshalb daraus eine weitere Komponente entstanden ist (generische abstrakte Factory), die der O/R Mapper verwendet.
Naja, so mal unter uns *einer unendlichen anzahl Personen gleichzeitig zuzwinker* am meisten hat mich der FoxPro-Style-Code unserer Firma dazu getrieben. Dann war es natülich eine schöne Herrausforderung. Und die O/R Mapper, die ich im Netz gefunden habe waren alle samt mehr oder weniger schlechte Code-Generatoren, die mir einweg DALs ausgespuckt haben.
An NHibernate (der einzige O/R Mapper, der mir sympatisch war) hat mich gestört, dass die Mappinginformationen von den Klassen getrannt ware - später hab ich dann erfahren, dass es auch mit NHibernate anders geht *grummel*.
Außerdem war es viel einfacher, meine Kollegen von OOP und einem O/R Mapper zu überzeugen, da mein O/R Mapper eine (oder DIE) Komponente verwendet, auf der unsere aktuelle Lösung beruhte.
So. Jetzt will ich das ganze zu einem Ende bringen. Hab ja genug geschwafelt.
Gruß
Juy Juka
ich stieß heute auf diesen Thread hier und finde es eine interessante Aufgabe die du dir da gestellt hast.
Zitat
Ein weiteres sehr wichtiges Ziel war es, die Datenbankzugriffe zu reduzieren. Durch das definieren von Chachespeichern (≤Klasse) lassen sich Gültigkeitsbereiche für persistente Objekte definieren
Hilf mir, aber ist das Zwischenspeichern nicht das größte Manko laut den O/R Mapper - Diskussionen? Wie sieht dein Speicherkonzept aus, wenn die Objekte sehr groß sind? Viele Fragen und ich hab nicht einmal eine Zeile Code gelesen Könntest du mir diesen zu kommen lassen? Bin schon gespannt
Zitat
NHibernate (der einzige O/R Mapper, der mir sympatisch war)
Das ist zur Zeit auch mein Favorit und ich habe mich gefragt: warum einer einen O/R-Mapper selber schreibt, wenn es Hibernate gibt. In der Java-Welt wird dieser in viellen ApplikationServern unterstüzt bzw. ist fest eingebunden. Das mit dem Mapping-Infos weist du ja jetzt und ich freue mich schon auf deinen Quellcode =)
... ist das Zwischenspeichern nicht das größte Manko laut den O/R Mapper - Diskussionen?
Die Kontrolle über den Cachespeicher liegt beim Programmierer, der meinen O/R Mapper verwendet. Wenn er glaubt, die Daten wieder aktuell zu brauchen, kann er ihn einfach weglassen und die gewünschten Objekte neu laden.
Zitat
Wie sieht dein Speicherkonzept aus, wenn die Objekte sehr groß sind?
Auch die Speicherkontrolle liegt überwiegend beim Programmierer, der meinen O/R Mapper verwendet. Mein O/R Mapper verwendet intern pro Objekt nur eine einzelne DataRow und verbraucht ansonsten nur minimal Speicher.
Außerdem nehem ich an, dass ohne hin etwas faul ist, wenn Objekte so groß werden, dass man sich sorgen um den Speicherverbraucht machen muss (Außnahem: Grafiken aller Art). Selbst 5.000 unserer größten Objekte (in unserer derzeitigen Anwendung) werden in Sekunden geladen und angezeigt (selbst wenn es die erste Anmeldung an der Datenbank ist, die bekanntlich länger dauert).
Zitat
...warum einer einen O/R-Mapper selber schreibt...
Ja, NHibernate hat sich im nachhinein besser herraus gestellt, als ich gedacht habe. *verflixt* Aber einen O/R-Mapper schreiben ist
A) eine super Herrausvorderung
B) SEHR Lehreich, für andere Tools, die einem das Leben später erleichtern
C) war super spassig
wie sieht den Dein Caching aus? Mein Caching funktioniert über eine Spalte Version in der eine Zahl gespeichert wird und wenn ich ein Refresh meiner Liste mache frage ich einfach nur
"WHERE Version > {HöchsteVersionAllerGeladenerObjekte}"
d.H. es kommen nur die 3 Datensätze die angefügt oder verändert wurden, gelöscht wird über
"UPDATE Table SET Deleted = TRUE, Version = {entsprechendeZahl}"
Zurück zur Frage, wie sieht Dein Caching aus?
mbg
Rossegger Robert
mehr fragen mehr wissen
Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen
Mein Caching "beschränkt" sich auf das einmalige Laden von Datensätzen inner halb eines Gültigkeitsbereiches.
Der Programmierer kann einen gültigkeits Bereich für Objekte definieren und wenn immer er eine Datenbankabfrage macht, wird vom O/R Mapper geprüft, obe er
1. Die ID des Objektes/Datensatzes vollständig abfragt.
2. Ob ein Objekt mit dieser ID bereits geladen ist.
Wenn beide Bedingungen zutreffen wird die gesammte Datenbankabfrage nicht ausgeführt und das bereits geladene Objekt zurück gegeben (das ist unendlich viel schneller).
Will der Programmierer ein "refresch" durchführen, so muss er den Gültigkeitsbreich "leeren" oder einen neuen Gültigkeitsbereich definieren.
d.h. der Programmierer leert den CacheCache aus? Sprich den Speicher der dem "Cache" zum cachen dient, verstehe ich, allerdings sehe ich hier das Problem, das es nicht zwingend ist dass die neuesten Daten von der Datenbank in meinem Programm sind. so ein Caching hat denke ich auch Gentle eingebaut, mit dem war ich dann sehr unglücklich und habe mir dann ein eigenes geschrieben.
Hast Du auch ein Transactionhandling drin?
mbg
Rossegger Robert
mehr fragen mehr wissen
Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen
Transaktionshandling ist auch drinen. Jedoch ein sehr loses händling.
Datensätze werden beim Auslesen nicht gelockt.
Beim zurückschreiben wird mit dem in .Net eingebauten Cuncurrency-Mechanismuss geprüft, ob der Datensatz von jemandem anderes geändert wurde und notfalls eine Exception geworfen.
Sollen mehrer Datensätze per Transaktion gespeichert werden, kann der Programmierer void SaveAsTransaction(IEnumerable<IAisysObject> objekte) aufrufen, oder ein Objekt, das selbst weiß, dass es aus mehreren Objekten besteht kann auch SaveAsTransaction aufrufen.