O/R-Mapping in .NET Das ADO.NET Entity Framework
O/R-Mapping in .NET Das ADO.NET Entity Framework
O/R-Mapping in .NET Das ADO.NET Entity Framework
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Fachhochschul-Bachelorstudiengang<br />
SOFTWARE ENGINEERING<br />
A-4232 Hagenberg, Austria<br />
O/R-<strong>Mapp<strong>in</strong>g</strong> <strong>in</strong> .<strong>NET</strong><br />
<strong>Das</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
Bachelorarbeit<br />
Teil 1<br />
zur Erlangung des akademischen Grades<br />
Bachelor of Science <strong>in</strong> Eng<strong>in</strong>eer<strong>in</strong>g<br />
E<strong>in</strong>gereicht von<br />
Günter Zöchbauer<br />
Begutachter: Dipl.-Ing. Johann He<strong>in</strong>zelreiter<br />
Hagenberg, Dezember 2008
© Copyright 2008 Günter Zöchbauer<br />
http://www.entityframework.de<br />
Alle Rechte vorbehalten
Inhaltsverzeichnis<br />
Kurzfassung iv<br />
Abstract v<br />
1 E<strong>in</strong>leitung und Motivation 1<br />
1.1 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />
1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />
1.3 Zielsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
2 Grundlagen 4<br />
2.1 O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> . . . . . . . . . . . . . . . . . . . . 4<br />
2.1.1 Wozu objektrelationale Abbildung? . . . . . . . . . . . 4<br />
2.1.2 Data Mapper . . . . . . . . . . . . . . . . . . . . . . . 5<br />
2.1.3 Metadaten-Abbildung bzw. O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> 5<br />
2.2 Abbildungsszenarien . . . . . . . . . . . . . . . . . . . . . . . 7<br />
2.2.1 Objektidentität . . . . . . . . . . . . . . . . . . . . . . 7<br />
2.2.2 Beziehungen . . . . . . . . . . . . . . . . . . . . . . . 8<br />
2.2.3 E<strong>in</strong>gebetteter Wert (Embedded Value) . . . . . . . . . 9<br />
2.2.4 Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />
2.2.5 Arbeitse<strong>in</strong>heit (Unit of Work) . . . . . . . . . . . . . . 12<br />
2.2.6 Nebenläufigkeit (Concurrency) . . . . . . . . . . . . . 13<br />
2.2.7 Laden bei Bedarf (Lazy Load<strong>in</strong>g) . . . . . . . . . . . . 13<br />
2.2.8 Unabhängigkeit der Entitätsklassen von der Persistenzschicht<br />
(Persistence Ignorance) . . . . . . . . . . . 14<br />
2.2.9 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . 14<br />
2.2.10 Weitere Aufgaben e<strong>in</strong>er O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung . . . . 15<br />
3 Evaluierung 17<br />
3.1 Verglichene Produkte . . . . . . . . . . . . . . . . . . . . . . . 17<br />
3.1.1 <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> . . . . . . . . . . . . . . 17<br />
3.1.2 Genome . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />
3.1.3 NHibernate . . . . . . . . . . . . . . . . . . . . . . . . 20<br />
3.2 Funktionalität . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />
3.2.1 Metadaten . . . . . . . . . . . . . . . . . . . . . . . . 21<br />
ii
Inhaltsverzeichnis iii<br />
3.2.2 Objektidentität . . . . . . . . . . . . . . . . . . . . . . 26<br />
3.2.3 Beziehungen . . . . . . . . . . . . . . . . . . . . . . . 28<br />
3.2.4 E<strong>in</strong>gebetteter Wert . . . . . . . . . . . . . . . . . . . . 30<br />
3.2.5 Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />
3.2.6 Nebenläufigkeit . . . . . . . . . . . . . . . . . . . . . . 30<br />
3.2.7 Abfragen . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />
3.3 Softwarearchitektur . . . . . . . . . . . . . . . . . . . . . . . . 32<br />
3.3.1 Unabhängigkeit der Entitätsklassen von der Persistenzschicht<br />
(Persistence Ignorance) . . . . . . . . . . . 32<br />
3.3.2 Unterstützte Datenbanksysteme . . . . . . . . . . . . 34<br />
3.4 Produktivität . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />
3.4.1 Codegenerierung . . . . . . . . . . . . . . . . . . . . . 34<br />
3.4.2 Designer-Werkzeug . . . . . . . . . . . . . . . . . . . . 36<br />
3.4.3 Visual Studio Integration . . . . . . . . . . . . . . . . 38<br />
4 Implementierung 39<br />
4.1 Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />
4.2 Realisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />
4.2.1 Visual Studio Projektorganisation . . . . . . . . . . . 40<br />
4.2.2 Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />
4.2.3 ID-Generierung . . . . . . . . . . . . . . . . . . . . . . 42<br />
4.2.4 Beziehungen . . . . . . . . . . . . . . . . . . . . . . . 44<br />
4.2.5 Fe<strong>in</strong>granulares Objektmodell . . . . . . . . . . . . . . 44<br />
4.2.6 Nebenläufigkeit . . . . . . . . . . . . . . . . . . . . . . 44<br />
5 Resumee und Ausblick 46<br />
5.1 Resumee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />
5.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />
Literaturverzeichnis 49
Kurzfassung<br />
Objektrelationale Abbildung (O/R-<strong>Mapp<strong>in</strong>g</strong>) ist das Überw<strong>in</strong>den der konzeptionellen<br />
und technischen Unterschiede zwischen dem Objektmodell <strong>in</strong><br />
objektorientierten Programmiersprachen und dem relationalem Modell <strong>in</strong><br />
Datenbankmanagementsystemen (RDBMS). So wird beispielsweise das Konzept<br />
der Vererbung im relationalen Modell nicht unterstützt. Auch die Identität<br />
von Entitäten sowie die Beziehungen zwischen Entitäten wird <strong>in</strong> diesen<br />
Modellen unterschiedlich dargestellt. <strong>Das</strong> Überw<strong>in</strong>den dieser Unterschiede<br />
stellt e<strong>in</strong>e erhebliche Herausforderung für Softwareentwickler dar.<br />
Für die Microsoft-.<strong>NET</strong>-Plattform wird e<strong>in</strong>e Reihe fertiger Produkte angeboten,<br />
die diese Abbildung übernehmen. Seit der Version 3.5 Service Pack<br />
1 ist das O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> <strong>in</strong>tegraler<br />
Bestandteil der Microsoft .<strong>NET</strong>-Plattform.<br />
Diese Arbeit untersucht, ob das <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> bereits<br />
für den produktiven E<strong>in</strong>satz geeignet ist und vergleicht den Funktionsumfang<br />
mit etablierten Produkten. Für diesen Vergleich wurde das kommerzielle<br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> Genome von TechTalk sowie das quelloffene<br />
NHibernate herangezogen. Im Rahmen dieser Arbeit werden die grundlegende<br />
Anforderungen an e<strong>in</strong> O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>, die Visual Studio-<br />
Integration, der Beitrag zu höherer Produktivität sowie der E<strong>in</strong>fluss auf die<br />
Softwarearchitektur untersucht.<br />
Mit e<strong>in</strong>er Beispielapplikation wird veranschaulicht, welche objektorientierten<br />
Konstrukte auf das relationale Modell abbildbar s<strong>in</strong>d und welche<br />
E<strong>in</strong>schränkungen gegebenenfalls bei den untersuchten Produkten zu berücksichtigen<br />
s<strong>in</strong>d.<br />
iv
Abstract<br />
Object-relational-mapp<strong>in</strong>g (O/R-mapp<strong>in</strong>g) is a technique to overcome the<br />
complexities when mapp<strong>in</strong>g objects of object oriented languages to the relational<br />
model of database management systems (RDBMS). For example,<br />
<strong>in</strong>heritance is not supported <strong>in</strong> the relational model. Even the identity of<br />
entities or the relations between entities are represented differently. A considerable<br />
effort is necessary by software eng<strong>in</strong>eers to overcome this mismatch.<br />
Several solutions are available for the Microsoft-.<strong>NET</strong> plattform which<br />
provide this functionality. With the release of .<strong>NET</strong> 3.5 Service Pack 1, the<br />
O/R mapp<strong>in</strong>g framework <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> became an <strong>in</strong>tegral<br />
part of the Microsoft .<strong>NET</strong> plattform.<br />
This thesis verifies if the <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> is applicable for a<br />
productive environment and compares its features with establied solutions.<br />
The commericial O/R-mapp<strong>in</strong>g framework Genome by TechTalk and the<br />
open source solution NHibernate are consulted for this comparsion.<br />
This paper exam<strong>in</strong>es and compares the basic features usually provided<br />
by O/R mapp<strong>in</strong>g frameworks, the <strong>in</strong>tegration <strong>in</strong>to Visual Studio as well as<br />
the benefit for productivity and its <strong>in</strong>fluence <strong>in</strong> software architectures.<br />
A sample application demonstrates object-relational constructs and how<br />
they are mappable via the O/R mapp<strong>in</strong>g frameworks. A special focus is set<br />
on the restrictions given by the exam<strong>in</strong>ed technologies.<br />
v
Kapitel 1<br />
E<strong>in</strong>leitung und Motivation<br />
1.1 Aufgabenstellung<br />
Diese Arbeit vergleicht <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> [26, 27], Microsofts<br />
neue O/R-<strong>Mapp<strong>in</strong>g</strong>-Technologie, mit zwei etablierten Produkten, NHibernate<br />
[40] sowie TechTalk Genome [59].<br />
Untersucht und gegenübergestellt werden die grundlegende Anforderungen<br />
an e<strong>in</strong> Persitenzframework, die Visual Studio-Integration, der Beitrag<br />
zu höherer Produktivität sowie Auswirkungen auf die Softwarearchitektur<br />
(z. B. <strong>in</strong> Bezug auf „Separation of concerns“). Des Weiteren wird untersucht,<br />
<strong>in</strong>wieweit die aktuelle Version des Microsoft <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
bereits für den produktiven E<strong>in</strong>satz geeignet ist.<br />
1.2 Motivation<br />
E<strong>in</strong> Großteil moderner Geschäftsapplikationen wird mittlerweile <strong>in</strong> objektorientierten<br />
Programmiersprachen wie Java und C# erstellt und die Objekte<br />
üblicherweise <strong>in</strong> e<strong>in</strong>er relationalen Datenbank persistiert. Zwischen Objektmodell<br />
und relationalem Modell der Datenbank gibt es e<strong>in</strong>ige technische und<br />
konzeptionelle Unterschiede. <strong>Das</strong> Überw<strong>in</strong>den dieser Unterschiede stellt e<strong>in</strong>e<br />
erhebliche Herausforderung für Softwareentwickler dar. Schon <strong>in</strong> den frühen<br />
90er-Jahren wurden z. B. für Smalltalk Standardlösungen angeboten 1 , die<br />
dem Entwickler diese Aufgabe abnehmen oder zum<strong>in</strong>dest erleichtern sollten.<br />
Die Popularität der Java-Plattform hat <strong>in</strong> diesem Bereich die Entwicklung<br />
vorangetrieben. Für Java gibt es seit e<strong>in</strong>igen Jahren leistungsfähig O/R-<br />
<strong>Mapp<strong>in</strong>g</strong>-Lösungen, die großteils quelloffen s<strong>in</strong>d und e<strong>in</strong>e weite Verbreitung<br />
gefunden haben. Mit JPA 2 hat Sun e<strong>in</strong>e e<strong>in</strong>heitliche API für die Nutzung<br />
1 z. B. Enterprise Objects <strong>Framework</strong>, das <strong>in</strong> Apples WebObjects [2] aufg<strong>in</strong>g oder Top-<br />
L<strong>in</strong>k [37, 52], das von Oracle <strong>in</strong> e<strong>in</strong>er Java-Version angeboten wird.<br />
2 Java Persistance API [55]<br />
1
1. E<strong>in</strong>leitung und Motivation 2<br />
verschiedener Persistenzframeworks <strong>in</strong> Java <strong>in</strong>tegriert.<br />
Im .<strong>NET</strong>-Umfeld besteht diesbezüglich noch Aufholbedarf. Es werden<br />
e<strong>in</strong>ige leistungsfähige O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen für .<strong>NET</strong> angeboten, doch<br />
Microsofts Ankündigung e<strong>in</strong> eigenes Produkt anzubieten, verunsicherte Anwender<br />
wie Mitbewerber. Verschärft wurde diese Situation dadurch, dass<br />
Microsoft das im Jahr 2001 erstmals angekündigte Produkt ObjectSpaces<br />
[8], [Esp04] aufgegeben hat um im Jahr 2005 dafür die neue Technologie<br />
LINQ 3 sowie <strong>Entity</strong> <strong>Framework</strong> anzukündigen [1, 5, 31].<br />
E<strong>in</strong>e O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung für e<strong>in</strong> Projekt e<strong>in</strong>zusetzen, hat weitreichende<br />
Auswirkungen auf die Softwarearchitektur. Die angebotenen Lösungen<br />
verfolgen teilweise unterschiedliche Ansätze mit unterschiedlichen APIs, wodurch<br />
es schwierig und kostspielig werden kann, die Entscheidung für e<strong>in</strong><br />
konkretes Produkt später zu revidieren.<br />
Laut aktuellem Informationsstand wird Microsoft <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
als Teil des .<strong>NET</strong>-<strong>Framework</strong>s ausgeliefert werden, somit kostenlos<br />
Verfügbar se<strong>in</strong> und nicht zuletzt deshalb e<strong>in</strong>e <strong>in</strong>teressante Option für viele<br />
Entwickler darstellen. Diese Lösung wird daher schon vor der endgültigen<br />
Fertigstellung untersucht, um frühzeitig e<strong>in</strong>e Entscheidungsgrundlage verfügbar<br />
zu haben.<br />
1.3 Zielsetzung<br />
Die Arbeit zeigt, <strong>in</strong>wieweit das Microsoft <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> <strong>in</strong><br />
der vorliegenden Version 4 e<strong>in</strong> ausgereiftes Produkt darstellt, das für den E<strong>in</strong>satz<br />
<strong>in</strong> komplexeren Projekten geeignet ist. Es untersucht, ob <strong>ADO</strong>.<strong>NET</strong><br />
<strong>Entity</strong> <strong>Framework</strong> bereits den Funktionsumfang etablierter Produkte anderer<br />
Hersteller bietet bzw. <strong>in</strong> welchen Bereichen es diesen überlegen ist.<br />
Unterschiedliche Lösungsansätze werden gegenübergestellt, ohne diese notwendigerweise<br />
zu bewerten.<br />
Dutzende kommerzielle und frei verfügbare Persistenzframeworks werden<br />
für Microsoft .<strong>NET</strong> angeboten. Da alle diese Produkte <strong>in</strong> den Vergleich<br />
e<strong>in</strong>zubeziehen, den Rahmen dieser Arbeit bei Weitem überschreiten würde,<br />
wurde die Auswahl auf zwei Produkte e<strong>in</strong>geschränkt, die mit dem <strong>ADO</strong>.<strong>NET</strong><br />
<strong>Entity</strong> <strong>Framework</strong> verglichen werden. Aus den verfügbaren quellofenen Lösungen<br />
wurde NHibernate, aus den kommerziellen Angeboten TechTalk Genome<br />
für den Vergleich ausgewählt. Alle drei Produkte verfolgen e<strong>in</strong>en ähnlichen<br />
Lösungsansatz, Abbildung per Metadaten, wobei NHibernate und<br />
<strong>Entity</strong> <strong>Framework</strong> für Objekterzeugung und Zugriff auf die <strong>Entity</strong>-Objekte<br />
hauptsächlich auf Reflection setzen, Genome h<strong>in</strong>gegen zur Übersetzungszeit<br />
den Quelltext für die Abbildung generieren.<br />
3 Language INtegrated Query<br />
4 Microsoft Visual Studio 2008 Service Pack 1 und .<strong>NET</strong> <strong>Framework</strong> 3.5 Service Pack<br />
1 [26, 28]
1. E<strong>in</strong>leitung und Motivation 3<br />
Neben den grundlegenden Funktionalitäten e<strong>in</strong>es O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>s<br />
wird untersucht, welche Unterstützung dem Softwareentwickler bei<br />
der Arbeit mit dem <strong>Framework</strong> geboten wird bzw. wie komfortabel der Entwickler<br />
damit arbeiten kann (z. B. welche Assistenten und grafische Werkzeuge<br />
für die Erstellung der Abbildungs-Metadaten und Enitätsklassen bereit<br />
gestellt werden), wie die Integration <strong>in</strong> Visual Studio realisiert wurde<br />
und wie weit es notwendig ist, die Softwarearchitektur e<strong>in</strong>er Anwendung auf<br />
das e<strong>in</strong>gesetzte Persistenzframework abzustimmen.<br />
Die e<strong>in</strong>zelnen Aspekte werden herausgearbeitet, <strong>in</strong>dem e<strong>in</strong>e Beispielanwendung<br />
realisiert wird, anhand derer die Umsetzung bestimmter Funktionalität<br />
mit den e<strong>in</strong>zelnen Testkandidaten untersucht und dargestellt wird.<br />
Nicht näher e<strong>in</strong>gegangen wird auf die von den Produkten angebotenen<br />
Abfragesprachen, Cach<strong>in</strong>g, Abbildung von Stored Procedures oder zusammengesetzte<br />
Primärschlüssel. Weitgehend unberücksichtigt bleiben Datenb<strong>in</strong>dung<br />
sowie generell die Anb<strong>in</strong>dung an die Benutzeroberfläche oder andere<br />
Clients. E<strong>in</strong> weiterer Aspekt der hier nicht untersucht wird, ist die<br />
Unterstützung von 3-Tier-Architektur, bei der persistente oder transiente<br />
Objekte bzw. Objektgraphen serialisiert über Prozess- und Rechnergrenzen<br />
h<strong>in</strong>weg übertragen werden.<br />
Außerdem wird davon ausgegangen, dass Microsoft Visual Studio 2008<br />
mit der .<strong>NET</strong>-Implementierung von Microsoft verwendet wird. Alternative<br />
.<strong>NET</strong>-Implementierungen (z. B. Mono [33]) oder IDEs (z. B. SharpDevelop<br />
[9]) bleiben unberücksichtigt.
Kapitel 2<br />
Grundlagen<br />
Die theoretischen Grundlagen für die Persistierung von Objekten <strong>in</strong> relationalen<br />
Datenbankmanagementsystemen (RDBMS) werden <strong>in</strong> der Literatur<br />
ausgiebig diskutiert (z. B. [Fus97,Amb06a,FRF02,Nil06]). Dieser Abschnitt<br />
stützt sich weitgehende auf die Ausführungen <strong>in</strong> [FRF02] und fasst die für<br />
die weitere Diskussion relevanten Themen zusammen.<br />
2.1 O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong><br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen s<strong>in</strong>d, nicht zuletzt seit Microsofts Ankündigung<br />
e<strong>in</strong> entsprechendes Produkt liefern zu wollen, e<strong>in</strong> viel diskutiertes Thema.<br />
Warum es s<strong>in</strong>nvoll se<strong>in</strong> kann, e<strong>in</strong>en O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> e<strong>in</strong>zusetzen,<br />
welche Aufgaben er erfüllen kann und welche Problematiken dabei auftreten,<br />
wird nachfolgend analysiert.<br />
2.1.1 Wozu objektrelationale Abbildung?<br />
Vor e<strong>in</strong>igen Jahren war es noch üblich, Geschäftslogik <strong>in</strong> der Datenbank<br />
(z. B. Oracle PL-SQL) oder <strong>in</strong> anderen prozeduralen Sprachen wie C, Pascal<br />
oder VisualBasic zu implementieren und ist auch noch heute <strong>in</strong> vielen<br />
Projekten gängige Praxis. Diese Vorgangsweise entspricht dabei meist dem<br />
unter [FRF02, S. 111] beschriebenen „Transaction Script“.<br />
“Organizes bus<strong>in</strong>ess logic by procedures where each procedure<br />
handles a s<strong>in</strong>gle request from the presentation.”<br />
Die E<strong>in</strong>fachheit ist der große Vorteil dieses Ansatzes und hat daher nach<br />
wie vor se<strong>in</strong>e Berechtigung. Bei e<strong>in</strong>facher Geschäftslogik ist es naheliegend,<br />
diesen Lösungsansatz zu wählen, da er leicht zu verstehen ist und der ger<strong>in</strong>ge<br />
Overhead sich positiv auf die Geschw<strong>in</strong>digkeit auswirkt.<br />
Steigende Komplexität der Geschäftslogik macht es zunehmend schwieriger,<br />
e<strong>in</strong>e übersichtliche Struktur beizubehalten. Jedes Transaktionsskript<br />
4
2. Grundlagen 5<br />
ist darauf ausgelegt, genau e<strong>in</strong>e Transaktion abzubilden. Dabei ist darauf<br />
zu achten, dass allgeme<strong>in</strong>er Code nicht mehrfach implementiert wird. Die<br />
Vorzüge der objektorientierten Programmierung (OOP), Komplexität durch<br />
Kapselung der Daten und Komb<strong>in</strong>ation mit zugehöriger Programmlogik <strong>in</strong><br />
Objekten sowie differenziertere Abbildung von Beziehungen mithilfe der Vererbung<br />
handhabbar zu machen, bleiben ungenutzt. Der <strong>in</strong> [FRF02, 116] als<br />
„Doma<strong>in</strong> Model“ beschriebene Ansatz (vgl. auch DDD (Doma<strong>in</strong>-Driven Design)<br />
[Eva03, Nil06]) rückt gerade diese Möglichkeiten <strong>in</strong> den Vordergrund.<br />
Bei e<strong>in</strong>em Domänenmodell kann zwischen e<strong>in</strong>fachem und komplexem<br />
Domänenmodell unterschieden werden, wobei das e<strong>in</strong>fache Domänenmodell<br />
weit gehend mit dem Datenbankschema übere<strong>in</strong>stimmt, das komplexe dagegen<br />
beträchtlich davon abweichen kann. Entsprechend aufwändig ist es,<br />
e<strong>in</strong> komplexes Domänenmodell <strong>in</strong> e<strong>in</strong> RDBMS zu persistieren, bzw. e<strong>in</strong>en<br />
Objektgraphen daraus wiederherzustellen. Für das e<strong>in</strong>fache Domänenmodell<br />
kann z. B. „Active Record“ [FRF02, S. 160] verwendet werden, für das<br />
komplexe ist dagegen e<strong>in</strong> „Data Mapper“ [FRF02, S. 165] erforderlich.<br />
2.1.2 Data Mapper<br />
E<strong>in</strong> Data Mapper ist e<strong>in</strong>e Vermittlungsschicht, die Daten zwischen Objekten<br />
im Speicher und Datenbank transferiert und dabei die technischen und<br />
konzeptionellen Unterschiede zwischen Objektmodell und relationalem Modell<br />
[Cod90], <strong>in</strong> der Literatur teilweise als „Object relation<strong>in</strong>al impedance<br />
mismatch“ [Amb06b] oder nur „Impedance Mismatch“ bezeichnet, überw<strong>in</strong>det.<br />
Objekte und Datenbank sollen möglichst unabhängig vone<strong>in</strong>ander<br />
bleiben und die Objekte ke<strong>in</strong>e Kenntnis über die Existenz der Datenbank,<br />
<strong>in</strong> die sie persistiert werden, benötigen (siehe Unterabschnitt 2.2.8).<br />
Vollständige Unabhängigkeit von der Persistenzschicht wird zwar angestrebt,<br />
ist aber kaum ohne schwerwiegende Nachteile, vor allem bzgl. Laufzeitoverhead,<br />
realisierbar [Nil06, S. 182]. Daher werden meist gewisse Kompromisse<br />
e<strong>in</strong>gegangen.<br />
Die Trennung zwischen Domänen- und relationalem Modell stellt sicher,<br />
dass beide Modelle unabhängig weiterentwickelt werden können und hat zusätzliche<br />
Vorteile wie z. B. die Möglichkeit, das Domänenmodell unabhängig<br />
von der Datenbank zu testen oder durch Austausch des Abbildungsframeworks<br />
<strong>in</strong> e<strong>in</strong> anderes RDBMS zu persistieren.<br />
2.1.3 Metadaten-Abbildung bzw. O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong><br />
E<strong>in</strong>e spezielle Ausprägung des Data Mapper-Entwurfsmusters ist „Metadata<br />
<strong>Mapp<strong>in</strong>g</strong>“ [FRF02, S. 306], die allgeme<strong>in</strong> als O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong><br />
bezeichnet wird (vgl. [Nil06, S. 289]).<br />
Für das Abbilden wird entweder e<strong>in</strong> universelles Data Mapper <strong>Framework</strong><br />
per Metadaten konfiguriert oder aus den Metadaten zur Kompilierzeit
2. Grundlagen 6<br />
Code für die konfigurierte Abbildung generiert. Mischformen s<strong>in</strong>d möglich<br />
und auch üblich.<br />
Per Metadaten wird def<strong>in</strong>iert, wie bestimmte Objekte und Objektgraphen<br />
<strong>in</strong> das relationale Modell transformiert bzw. wie aus diesen persistierten<br />
Daten Objekte rekonstruiert werden sollen. Die Metadaten liegen<br />
üblicherweise als XML-Datei vor oder s<strong>in</strong>d als Attribute <strong>in</strong> die Klassendef<strong>in</strong>itionen<br />
e<strong>in</strong>gebettet.<br />
E<strong>in</strong>e O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung abstrahiert das e<strong>in</strong>gesetzte RDBMS weitgehend<br />
und bietet e<strong>in</strong>e Schnittstelle mit Methoden, um z. B. neue Objekte<br />
für die Persistierung zu registrieren oder Abfragen auszuführen und die entsprechenden<br />
Objekte zurückzuliefern. Die Kommunikation mit dem RDBMS<br />
sowie die Umsetzung der Methodenaufrufe <strong>in</strong> SQL-DML 1 -Statements erfolgt<br />
transparent. Durch das Zusammenfassen des Datenbankzugriffes <strong>in</strong> e<strong>in</strong>er eigenen<br />
Schicht (Layer [FRF02, S. 17]), wird die Komplexität der Applikation<br />
reduziert.<br />
Im Detail führt das zu e<strong>in</strong>er Reihe von Aufgaben, die zu lösen s<strong>in</strong>d. Nicht<br />
jeder O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung unterstützt alle möglichen Szenarien. [Fus97]<br />
unterscheidet z. B. fünf Ausbaustufen.<br />
E<strong>in</strong>fache O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen bilden nur Objekte ab, deren Strukturen<br />
dem Datenbankschema direkt entsprechen (e<strong>in</strong>faches Domänenmodell).<br />
Leistungsfähigere O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen können auch Objektmodelle persistieren,<br />
die weitere Ausdrucksmöglichkeiten der OOP nutzen, für die ke<strong>in</strong>e<br />
direkte Entsprechung im relationalen Modell existiert, z. B. Vererbung (komplexes<br />
Domänenmodell).<br />
Für e<strong>in</strong>e Geschäftstransaktion wird e<strong>in</strong> Teil der Daten aus der Datenbank<br />
angefordert und als Objekte rekonstruiert. Diese Objekte werden während<br />
der Transaktion geändert, gelöscht bzw. neue Objekte erstellt. <strong>Das</strong> Zusammenführen<br />
dieser Änderungen mit dem Datenbestand im RDBMS am Ende<br />
der Transaktion gehört zu den Aufgaben des O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>s.<br />
Dabei darf der bei RDBMS übliche gleichzeitige Zugriff mehrerer Clients<br />
nicht zu <strong>in</strong>konsistenten Daten führen.<br />
Üblicherweise wird e<strong>in</strong> O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> mit e<strong>in</strong>em Satz von<br />
Werkzeugen wie grafische Designer und Assistenten geliefert, die dem Entwickler<br />
das Entwerfen der Entitätsklassen und der Konfiguration der Abbildung<br />
erleichtern. Je nach Lösungsansatz wird automatisch Code für Entitätsklassen<br />
und das Abbilden generiert.<br />
Optimierungen s<strong>in</strong>d notwendig, damit der gewonnene Komfort möglichst<br />
nicht durch E<strong>in</strong>bußen bei der Geschw<strong>in</strong>digkeit erkauft wird.<br />
1 Data Manipulation Language
2. Grundlagen 7<br />
2.2 Abbildungsszenarien<br />
E<strong>in</strong>e O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung benötigt Strategien für verschiedenste Konstrukte<br />
und Szenarien, auf die nachfolgend näher e<strong>in</strong>gegangen wird.<br />
Je nach Konfiguration und Unterstützung durch das verwendete O/R-<br />
<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> werden Properties oder private oder öffentliche Datenkomponenten<br />
persistiert. In weiterer Folge wird <strong>in</strong> diesem Zusammenhang<br />
nur der Begriff Properties verwendet.<br />
2.2.1 Objektidentität<br />
Entitäten (vgl. Entities [Eva03, S. 89] und [Nil06, S. 462]) im Arbeitsspeicher<br />
müssen den zugehörigen Datensätzen <strong>in</strong> der Datenbank e<strong>in</strong>deutig zuordenbar<br />
se<strong>in</strong>. Die Identität von Objekten ist anders def<strong>in</strong>iert (z. B. über<br />
die Adresse im Arbeitsspeicher) als die von Datensätzen <strong>in</strong> e<strong>in</strong>em RDBMS,<br />
die über den Primärschlüssel, e<strong>in</strong> oder mehrere Attribute des Datensatzes,<br />
identifiziert werden.<br />
Der Primärschlüssel (Primary key, PK) kann auf unterschiedlich Weise<br />
gebildet werden, z. B. als natürlicher Schlüssel (Mean<strong>in</strong>gful key, Natural<br />
key), wobei bestehende Attribute als Primärschlüssel verwendet werden.<br />
E<strong>in</strong>e bessere Alternative, vor allem für den E<strong>in</strong>satz mit O/R-<strong>Mapp<strong>in</strong>g</strong>-<br />
Lösungen, s<strong>in</strong>d künstliche Schlüssel (Mean<strong>in</strong>gless key, Surrogate key, Surrogat).<br />
Dabei wird e<strong>in</strong>e zusätzliches Attribut e<strong>in</strong>gefügt, dessen Bedeutung<br />
ausschließlich dar<strong>in</strong> besteht, den Datensatz e<strong>in</strong>deutig zu identifizieren. Werden<br />
natürliche Schlüssel verwendet, führt das, z. B. bei m:n-Beziehungen, zu<br />
komb<strong>in</strong>ierten Schlüsseln, bei denen mehrere Attribute den Primärschlüssel<br />
bilden. Komb<strong>in</strong>ierte Schlüssel verkomplizieren das Abbilden.<br />
Die Werte für künstliche Schlüssel können aus unterschiedlichen Wertebereichen<br />
gebildet werden, z. B. 64-Bit-Ganzzahl, wobei E<strong>in</strong>deutigkeit pro<br />
Tabelle oder für die gesamte Datenbank gewählt werden kann. Ist E<strong>in</strong>deutigkeit<br />
über mehrere Datenbanken gefordert, weil diese synchronisiert werden,<br />
bietet sich der GUID 2 -Datentyp an, der aber mehr Speicher benötigt (128<br />
Bit) und somit die Indizes vergrößert (vgl. [Nil02]).<br />
Weiters ist zu unterscheiden, wo und zu welchem Zeitpunkt die Schlüsselwerte<br />
generiert werden. E<strong>in</strong>ige RDBMS bieten dafür spezielle Mechanismen<br />
wie Sequence (z. B. ORACLE) oder Identity Field (z. B. Microsoft SQL-<br />
Server). <strong>Das</strong> Identity-Field des Microsoft SQL-Server hat bei Verwendung<br />
mit e<strong>in</strong>em O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> den Nachteil, dass die neue ID erst<br />
beim E<strong>in</strong>fügen <strong>in</strong> die Datenbank generiert wird. Soll z. B. e<strong>in</strong> neuer Auftrag<br />
gespeichert werden, muss zuerst der Order-Datensatz gespeichert werden,<br />
danach muss die vom RDBMS generierte ID mit e<strong>in</strong>er zusätzlichen Datenbankoperation<br />
ausgelesen werden, damit diese für den nächsten Schritt, das<br />
Speichern der Auftragspositionen als Fremdschlüssel (Foreign key, FK) zur<br />
2 Global Unique Identifier
2. Grundlagen 8<br />
Verfügung steht. Dadurch werden zusätzliche zeitaufwändige Datenbankzugriffe<br />
notwendig.<br />
Wesentlich effizienter ist die <strong>in</strong> ORACLE verfügbare Sequence. Es kann<br />
vorab e<strong>in</strong>e beliebige Anzahl von IDs angefordert werden, die vom ORM sukzessiv<br />
für neue Objekte vergeben werden bis sie aufgebraucht s<strong>in</strong>d. Je mehr<br />
Werte auf e<strong>in</strong>mal angefordert werden, umso weniger Datenbankzugriffe s<strong>in</strong>d<br />
<strong>in</strong>sgesamt dafür notwendig, aber umso mehr IDs werden im Durchschnitt<br />
verschwendet. E<strong>in</strong>mal angeforderte IDs, sollten sie nicht aufgebraucht werden,<br />
weil die Applikation vorher beendet wurde, können nicht zurückgegeben<br />
werden und s<strong>in</strong>d damit endgültig verloren. Bei e<strong>in</strong>em ausreichend großen<br />
Wertebereich, z. B. 64-Bit-Ganzzahl, stellt das <strong>in</strong> der Praxis üblicherweise<br />
ke<strong>in</strong> Problem dar.<br />
Wird der Sequence-Mechanismus vom verwendeten RDBMS nicht zur<br />
Verfügung gestellt, kann diese Funktion leicht nachgebildet werden. E<strong>in</strong>e eigene<br />
Tabelle enthält e<strong>in</strong>e Spalte und e<strong>in</strong>en Datensatz mit der bisher höchsten<br />
vergebenen ID. Soll die ID pro Tabelle e<strong>in</strong>deutig se<strong>in</strong>, wird e<strong>in</strong>e weiteres Attribut<br />
mit dem Tabellennamen und für jede Tabelle e<strong>in</strong> Datensatz benötigt.<br />
Der Wert erhöht sich jeweils um die Anzahl angeforderter IDs. <strong>Das</strong> Anfordern<br />
der IDs muss <strong>in</strong> e<strong>in</strong>er eigenen Transaktion durchgeführt werden, da<br />
ansonsten Optimistic Offl<strong>in</strong>e Lock (siehe Unterabschnitt 2.2.6) nicht funktionieren<br />
würde.<br />
GUIDs können direkt vom O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> generiert werden<br />
und benötigen daher ke<strong>in</strong>e zusätzlichen Datenbankzugriffe.<br />
Für die Verwendung mit e<strong>in</strong>em O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung s<strong>in</strong>d deshalb e<strong>in</strong>fache<br />
künstliche Schlüssel, die per Sequence-Mechanismus generiert werden<br />
sowie GUID oft die beste Lösung.<br />
2.2.2 Beziehungen<br />
Beziehungen zwischen Objekten s<strong>in</strong>d unidirektional und werden mit Datenkomponenten,<br />
die e<strong>in</strong> weiteres Objekt referenzieren, dargestellt (1:1). Mehrere<br />
Objekte gleichen Typs werden referenziert, <strong>in</strong>dem e<strong>in</strong>e Behälterklasse als<br />
Datenkomponente verwendet wird (1:n). Bidirektionale Beziehungen werden<br />
als zwei unidirektionale Beziehungen abgebildet. Mit zwei 1:n-Beziehungen<br />
kann e<strong>in</strong>e m:n-Beziehung erstellt werden. E<strong>in</strong>e Objektreferenz kann Objekte<br />
jener Typen referenzieren, die dem Typ der Datenkomponente oder e<strong>in</strong>em<br />
davon abgeleiteten Typ entsprechen und s<strong>in</strong>d damit polymorph.<br />
Beziehungen im Relationenmodell werden durch Attribute abgebildet.<br />
Der Primärschlüssel e<strong>in</strong>er Tabelle wird als Fremdschlüssel <strong>in</strong> der referenzierten<br />
Tabelle verwendet. Die Datensätze beider Tabellen s<strong>in</strong>d referenziert,<br />
wenn Primärschlüssel und Fremdschlüssel die gleichen Werte enthalten.<br />
Grundsätzlich bietet das Relationenmodell nur bidirektionale 1:n-Beziehungen,<br />
die mit Hilfe von E<strong>in</strong>schränkungen (Constra<strong>in</strong>ts) auf 1:1 beschränkt<br />
werden können. Mit e<strong>in</strong>er zusätzlichen Beziehungstabelle, zu denen zwei Ta-
2. Grundlagen 9<br />
bellen e<strong>in</strong>e 1:n-Beziehung def<strong>in</strong>ieren, wird e<strong>in</strong>e m:n-Beziehung abgebildet.<br />
Dieses Behelfskonstrukt ist bei m:n-Beziehungen zwischen Objekten nicht<br />
notwendig. Für Polymorphismus werden im Relationenmodell ke<strong>in</strong>e speziellen<br />
Konstrukte angeboten, die Funktionalität kann aber auf verschiedene<br />
Weise nachgebildet werden und erfordert <strong>in</strong> erster L<strong>in</strong>ie entsprechend<br />
gestaltete Abfragen. Weiterführende Informationen dazu f<strong>in</strong>den sich unter<br />
„Foreign Key <strong>Mapp<strong>in</strong>g</strong>“ <strong>in</strong> [FRF02, S. 136] für 1:n-Beziehungen sowie unter<br />
„Association Table <strong>Mapp<strong>in</strong>g</strong>“ [FRF02, 248] für m:n-Beziehungen.<br />
2.2.3 E<strong>in</strong>gebetteter Wert (Embedded Value)<br />
Objekte s<strong>in</strong>d oft fe<strong>in</strong>granularer als Datenbanktabellen (F<strong>in</strong>e-gra<strong>in</strong>ed object<br />
model [KBK08]) um Daten und zugehöriges Verhalten sauber zu kapseln. So<br />
kann es s<strong>in</strong>nvoll se<strong>in</strong>, beispielsweise bei e<strong>in</strong>em Customer-Objekt die Address-<br />
Properties <strong>in</strong> e<strong>in</strong> eigenes Address-Objekt auszulagern, das vom Customer-<br />
Objekt nur referenziert wird. Im relationalen Modell bietet diese Aufteilung<br />
ke<strong>in</strong>en Vorteil. Dort gibt es nur Daten ohne Verhalten, und daher ke<strong>in</strong>e Notwendigkeit<br />
für Kapselung. Würden die Objekte <strong>in</strong> unterschiedlichen Tabellen<br />
abgebildet, müssten bei Abfragen die Datensätze aus unterschiedlichen<br />
Tabellen wieder zusammengeführt werden. <strong>Das</strong> ist zeit<strong>in</strong>tensiv und deshalb<br />
nach Möglichkeit zu vermeiden. Die Properties des Address-Objektes sollen<br />
daher <strong>in</strong> die Customer-Tabelle e<strong>in</strong>gebettet werden.<br />
Unter [FRF02, S. 268] wird auf diese Funktionalität ausführlich e<strong>in</strong>gegangen.<br />
2.2.4 Vererbung<br />
<strong>Das</strong> Relationenmodell <strong>in</strong> RDBMS sieht ke<strong>in</strong>e Vererbung vor, daher werden<br />
Strategien benötigt, um Vererbungshierarchien <strong>in</strong> Datenbanken abzubilden.<br />
Es stehen drei Möglichkeiten zur Auswahl, bei denen es unterschiedliche<br />
Vor- und Nachteile abzuwägen gilt. Die Abbildung e<strong>in</strong>er Klassenhierarchie<br />
muss nicht auf e<strong>in</strong>e dieser Strategien beschränkt bleiben. Für Teilhierarchien<br />
können unterschiedliche Varianten verwendet werden.<br />
Vererbungshierarchie <strong>in</strong> e<strong>in</strong>er Tabelle (S<strong>in</strong>gle Table Inheritance)<br />
Bei Vererbungshierarchie <strong>in</strong> e<strong>in</strong>er Tabelle (S<strong>in</strong>gle Table Inheritance) wird die<br />
gesamte Hierarchie <strong>in</strong> e<strong>in</strong>er Tabelle abgelegt (siehe Abbildung 2.1). Jedes<br />
Objekt wird durch e<strong>in</strong>en Datensatz repräsentiert, wobei nur die Attribute<br />
befüllt werden, die <strong>in</strong> der konkreten Klasse vorkommen. Die restlichen Attribute<br />
bekommen den Wert null. <strong>Das</strong> heißt, dass alle zu persistierenden<br />
Properties der Klassen der Hierarchie als Attribut <strong>in</strong> der Tabelle vorkommen.<br />
Zusätzlich wird e<strong>in</strong> Diskrim<strong>in</strong>ator benötigt, der die konkrete Klasse<br />
identifiziert, die beim Laden aus e<strong>in</strong>em Datensatz erzeugt werden soll.
2. Grundlagen 10<br />
club<br />
Footballer<br />
name<br />
Player<br />
Cricketer<br />
batt<strong>in</strong>g average<br />
Bowler<br />
bowl<strong>in</strong>g average<br />
Abbildung 2.1: S<strong>in</strong>gle Table Inheritance [FRF02, S. 278].<br />
«table»<br />
Players<br />
name<br />
club<br />
batt<strong>in</strong>g average<br />
bowl<strong>in</strong>g average<br />
type<br />
Der Vorteil ist, dass für die gesamte Hierarchie nur e<strong>in</strong>e Tabelle benötigt<br />
wird. Beim Laden entfällt das zusammenführen (Jo<strong>in</strong>) mehrerer Tabellen,<br />
Abfragen s<strong>in</strong>d entsprechend effizient. Polymorphe Relationen können damit<br />
abgebildet werden.<br />
Nachteilig wirkt sich aus, dass <strong>in</strong> der Tabelle die Zahl der Attribute<br />
schnell anwachsen kann. Def<strong>in</strong>ieren die abgeleiteten Klassen eigene Properties,<br />
werden <strong>in</strong> der Tabelle entsprechend viele Spalten benötigt, obwohl<br />
bei jedem e<strong>in</strong>zelnen Datensatz nur e<strong>in</strong> Teil davon belegt wird. Außer bei<br />
den Attributen der Basisklasse ist es daher nicht möglich, „NOT NULL“-<br />
E<strong>in</strong>schränkungen zu def<strong>in</strong>ieren. Werden <strong>in</strong> verschiedenen Subklassen gleichnamige<br />
Properties e<strong>in</strong>geführt, entstehen Konflikte die aufgelöst werden müssen,<br />
z. B. durch voranstellen e<strong>in</strong>es spezifischen Präfixes für jede Subklasse.<br />
Vererbung mit e<strong>in</strong>er Tabelle pro Klasse (Class Table Inheritance)<br />
Bei Vererbung mit e<strong>in</strong>er Tabelle pro Klasse wird für jede Klasse der Hierarchie<br />
e<strong>in</strong>e Tabelle erstellt, wobei für die <strong>in</strong> e<strong>in</strong>er Subklasse zusätzlich def<strong>in</strong>ierten<br />
Properties e<strong>in</strong>e eigene Tabelle verwendet wird (siehe Abbildung 2.2).<br />
E<strong>in</strong> Vorteil gegenüber Vererbungshierarchie <strong>in</strong> e<strong>in</strong>er Tabelle ist, dass ke<strong>in</strong>e<br />
Spalten ungenützt bleiben. Nachteilig wirkt sich aus, dass beim Laden die<br />
Tabellen wieder zusammengeführt werden müssen. Wobei pro Datensatz, abhängig<br />
vom konkreten Typ, unterschiedliche Tabellen zu komb<strong>in</strong>ieren s<strong>in</strong>d.<br />
Vor allem bei Klassenhierarchien mit mehr als drei Tabellen bee<strong>in</strong>trächtigt<br />
das die Geschw<strong>in</strong>digkeit, da RDBMS üblicherweise nur für Jo<strong>in</strong>s mit bis zu<br />
drei Tabellen optimiert s<strong>in</strong>d.
2. Grundlagen 11<br />
club<br />
club<br />
Footballer<br />
Footballer<br />
name<br />
Player<br />
Cricketer<br />
batt<strong>in</strong>g average<br />
Bowler<br />
bowl<strong>in</strong>g average<br />
Abbildung 2.2: Class Table Inheritance [FRF02, S. 285].<br />
name<br />
Player<br />
Cricketer<br />
batt<strong>in</strong>g average<br />
Bowler<br />
bowl<strong>in</strong>g average<br />
«table»<br />
Footballers<br />
club<br />
«table»<br />
Cricketers<br />
batt<strong>in</strong>g average<br />
«table»<br />
Bowlers<br />
bowl<strong>in</strong>g average<br />
«table»<br />
Players<br />
name<br />
«table»<br />
Footballers<br />
name<br />
club<br />
«table»<br />
Cricketers<br />
name<br />
batt<strong>in</strong>g average<br />
«table»<br />
Bowlers<br />
name<br />
batt<strong>in</strong>g average<br />
bowl<strong>in</strong>g average<br />
Abbildung 2.3: Concrete Table Inheritance [FRF02, S. 293].<br />
Vererbung mit e<strong>in</strong>er Tabelle pro konkreter Klasse (Concrete Table<br />
Inheritance)<br />
Bei Vererbung mit e<strong>in</strong>er Tabelle pro konkreter Klasse (Concrete Table Inheritance)<br />
wird für jede konkrete Klasse der Hierarchie e<strong>in</strong>e Tabelle angelegt<br />
(siehe Abbildung 2.3). Alle Properties der konkreten Klasse sowie die aller<br />
direkten und <strong>in</strong>direkten Superklassen werden <strong>in</strong> dieser Tabelle abgelegt.
2. Grundlagen 12<br />
Die Properties der Superklassen kommen daher <strong>in</strong> allen Tabellen vor, deren<br />
Klassen von dieser Superklasse ableiten.<br />
Wie bei Vererbung mit e<strong>in</strong>er Tabelle pro Klasse werden bei jedem Datensatz<br />
alle Attribute belegt, weiters werden beim Laden ke<strong>in</strong>e Jo<strong>in</strong>s benötigt.<br />
Wesentliche Nachteile s<strong>in</strong>d, dass bei Abfragen auf e<strong>in</strong>e Basisklasse Unions<br />
notwendig s<strong>in</strong>d, sowie bei Änderungen an Attributen e<strong>in</strong>er Basisklasse,<br />
die Änderungen <strong>in</strong> allen Tabellen abgeleiteter Klassen durchgeführt werden<br />
müssen.<br />
2.2.5 Arbeitse<strong>in</strong>heit (Unit of Work)<br />
Wird jede e<strong>in</strong>zelne Datenänderung an e<strong>in</strong>em Objekt im Speicher e<strong>in</strong>zeln<br />
<strong>in</strong> die Datenbank geschrieben, resultiert das <strong>in</strong> e<strong>in</strong>er Unmenge von Datenbankzugriffen.<br />
Dadurch wird die Skalierbarkeit drastisch e<strong>in</strong>geschränkt, auch<br />
deshalb, weil e<strong>in</strong>e Datenbanktransaktion vom ersten bis zum letzten Zugriff<br />
offen gehalten werden muss. Dieses Problem kann umgangen werden, <strong>in</strong>dem<br />
die Änderungen im Arbeitsspeicher mitprotokolliert und dann gebündelt an<br />
die Datenbank abgesetzt werden („Unit of Work“ [FRF02, S. 184]).<br />
E<strong>in</strong>e Arbeitse<strong>in</strong>heit muss von den Datenänderungen erfahren, um sie<br />
protokollieren zu können. Entweder wird die Arbeitse<strong>in</strong>heit explizit von jeder<br />
Änderung benachrichtigt oder es werden Mechanismen implementiert, mit<br />
denen die Arbeitse<strong>in</strong>heit Änderungen selbständig eruieren kann.<br />
Explizite Benachrichtigungen haben den Nachteil, dass sie leicht vergessen<br />
werden. Sollen die Objekte selbständig Änderungen melden, müssen diese<br />
Kenntnis vom Abbildungs-<strong>Framework</strong> haben, womit die Unabhängigkeit<br />
von der Persistenzschicht (siehe Unterabschnitt 2.2.8) aufgeweicht wird.<br />
Werden lesende Zugriffe auf die Datenbank mit der Arbeitse<strong>in</strong>heit komb<strong>in</strong>iert,<br />
können Kopien der zurückgelieferten Objekte zum späteren Vergleich<br />
behalten werden, um damit Änderungen automatisch festzustellen<br />
(<strong>in</strong> [FRF02, S. 187] als „Unit of Work Controller“ bezeichnet). Der Nachteil<br />
hierbei ist, dass alle Objekte doppelt im Speicher angelegt werden.<br />
E<strong>in</strong>e alternative Möglichkeit ist, dass die Zugriffsoperationen von den<br />
Entitätsklassen abgeleitete Klassen liefern (Proxy [GHJV04, S. 254]), die<br />
die Properties überschreiben und so erweitern, dass die Arbeitse<strong>in</strong>heit von<br />
Änderungen benachrichtigt wird.<br />
Durch das Zusammenfassen aller Änderungen e<strong>in</strong>er Geschäftstransaktion<br />
geht die Reihenfolge der Änderungen verloren. Wird nicht e<strong>in</strong>e bestimmte<br />
Reihenfolge e<strong>in</strong>gehalten besteht die Gefahr, dass die referentielle Integrität<br />
verletzt wird, oder es zu Deadlocks kommt. Aufgabe der Arbeitse<strong>in</strong>heit ist<br />
es daher, vor dem Absetzen der DMS-Statements an die Datenbank die<br />
Reihenfolge so zu sortieren, dass alle Abhängigkeiten aufgelöst s<strong>in</strong>d.
2. Grundlagen 13<br />
2.2.6 Nebenläufigkeit (Concurrency)<br />
Optimistische verb<strong>in</strong>dungslose Sperre (Optimistic Offl<strong>in</strong>e Lock) [FRF02, S.<br />
416] ist e<strong>in</strong>e Methode, die Daten<strong>in</strong>konsistenzen bei konkurrierenden Datenänderungen<br />
gleichzeitig ablaufender Transaktionen verh<strong>in</strong>dert.<br />
Realisiert wird diese Konflikterkennung durch e<strong>in</strong> zusätzliches Attribut<br />
<strong>in</strong> jeder Tabelle, das bei jeder Datenänderung <strong>in</strong>krementiert wird und somit<br />
die Version e<strong>in</strong>es Datensatzes def<strong>in</strong>iert. Vor dem Schreiben der Änderung<br />
wird geprüft, ob die Version <strong>in</strong> der Datenbank noch mit der des Lesezeitpunktes<br />
übere<strong>in</strong>stimmt. Ist sie unverändert, wird die Änderung durchgeführt.<br />
Wurde der Datensatz <strong>in</strong> der Zwischenzeit von e<strong>in</strong>er anderen Transaktion<br />
geändert oder gelöscht, besteht e<strong>in</strong> Konflikt und die laufende Transaktion<br />
muss mit e<strong>in</strong>em Rollback abgebrochen werden.<br />
Optimistische Verb<strong>in</strong>dungslose Sperre lässt mehr gleichzeitige Datenzugriffe<br />
zu als Datenbanktransaktionen und verbessert damit den Durchsatz.<br />
Nachteilig wirkt sich aus, dass erst am Ende der Geschäftstransaktion<br />
geprüft wird, ob e<strong>in</strong> Konflikt besteht. Dadurch kann es passieren, dass<br />
zeitaufwändig erfasste E<strong>in</strong>gaben verworfen und von Neuem erstellt werden<br />
müssen. <strong>Das</strong> kann zu Akzeptanzproblemen bei den Anwendern führen.<br />
2.2.7 Laden bei Bedarf (Lazy Load<strong>in</strong>g)<br />
Für jedes Transaktionsskript (siehe Unterabschnitt 2.1.1) kann e<strong>in</strong>e angepasste<br />
SQL-Abfrage erstellt werden, die genau jene Daten liefert, die für<br />
die Transaktion benötigt werden, mit Hilfe von entsprechenden Jo<strong>in</strong>s und<br />
Projektionen. E<strong>in</strong> Data Mapper ist allerd<strong>in</strong>gs vollkommen unabhängig von<br />
der Geschäftslogik. Unter dieser Voraussetzung lautet e<strong>in</strong> e<strong>in</strong>facher Ansatz,<br />
jedes angeforderte Objekt e<strong>in</strong>zeln aus der Datenbank zu laden.<br />
Wird beispielsweise auf e<strong>in</strong>e Auftragsposition zugegriffen, werden oft<br />
auch die zugehörigen Auftragspositionen benötigt. Bei e<strong>in</strong>em darauf folgenden<br />
Zugriff auf jede Auftragsposition würde dadurch e<strong>in</strong> neuerlichen Datenbankzugriff<br />
verursacht, obwohl es wesentlich effizienter wäre, den Auftrag<br />
mit allen Auftragspositionen mit e<strong>in</strong>em Zugriff (z. B. Jo<strong>in</strong>) zu laden.<br />
Würden bei e<strong>in</strong>em Zugriff auf e<strong>in</strong>en Datensatz alle Detaildatensätze automatisch<br />
mit geladen, müssten mit e<strong>in</strong>em Zugriff auf e<strong>in</strong>en Kunden alle<br />
erteilten Aufträge dieses Kunden und alle zugehörigen Positionsdaten und<br />
die dar<strong>in</strong> referenzierten Artikeldaten usw. geladen werden. <strong>Das</strong> würde dazu<br />
führen, dass der Zugriff auf e<strong>in</strong>en Kunden be<strong>in</strong>ahe die gesamte Datenbank<br />
<strong>in</strong> den Arbeitsspeicher lädt. Also muss der Automatismus irgendwo unterbrochen<br />
werden. Dieses Problem kann mittels „Lazy Load<strong>in</strong>g“ [FRF02, S.<br />
200] gelöst werden.
2. Grundlagen 14<br />
2.2.8 Unabhängigkeit der Entitätsklassen von der Persistenzschicht<br />
(Persistence Ignorance)<br />
Um den „Doma<strong>in</strong>-Layer“ [Eva03, S. 75] von Infrastrukturcode freizuhalten,<br />
also e<strong>in</strong>e saubere Trennung zwischen den Schichten beizubehalten, ist<br />
es wichtig, die Entitätsklassen weitgehend unabhängig vom O/R-<strong>Mapp<strong>in</strong>g</strong>-<br />
<strong>Framework</strong> zu halten. Diese Trennung wird angestrebt, um das Designpr<strong>in</strong>zip<br />
„Separation of concerns“ [Dij82] möglichst sauber umsetzen zu können.<br />
Entitätsklassen sollen nach Möglichkeit ke<strong>in</strong>e Kenntnis davon haben,<br />
dass sie überhaupt persistiert werden. Diese Anforderung wird üblicherweise<br />
als „Persitence Ignorance“ [Nil06, S. 182] bezeichnet. Klassen, die frei<br />
von Persistierungscode s<strong>in</strong>d, werden als POCO (Pla<strong>in</strong> old CLR Object oder<br />
unter Java als POJO) bezeichnet. Verschiedene Anforderungen an den O/R-<br />
<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>, z. B. Setzen von privaten Properties beim Wiederherstellen<br />
von persistenten Objekten oder automatische Änderungsverfolgung,<br />
widersprechen dieser Anforderung.<br />
Es gibt verschiedene Ansätze, Unabhängigkeit von der Persistenzschicht<br />
zu realisieren, Kompromisse s<strong>in</strong>d aber unumgänglich. Teilweise wird Reflection<br />
verwendet, um auf private Properties zuzugreifen oder e<strong>in</strong> Konstruktor<br />
wird gefordert, der für alle Properties entsprechende Parameter vorsieht.<br />
Müssen Entitätsklassen e<strong>in</strong> bestimmtes Interfaces implementieren, um<br />
den Zugriff auf Internas der Objekte zu ermöglichen, wird das auch als IPO-<br />
CO (Interface-POCO) bezeichnet [34, 50].<br />
Unumgänglich ist weiters die Implementierung e<strong>in</strong>er Property für den<br />
Primärschlüssel. Vollständige Unabhängigkeit von der Persistenzschicht ist<br />
daher kaum realisierbar.<br />
2.2.9 Konfiguration<br />
Die <strong>in</strong> dieser Arbeit untersuchten Produkte s<strong>in</strong>d Meta Data Mapper (siehe<br />
Unterabschnitt 2.1.3). <strong>Das</strong> bedeutet, die Abbildung der Klassen und Objekte<br />
auf die Datenbank wird per Metadaten def<strong>in</strong>iert.<br />
Metadaten können als XML-Dateien vorliegen oder als Attribute <strong>in</strong> den<br />
Entitätsklassen e<strong>in</strong>gebettet se<strong>in</strong>. Je nach Implementierung werden diese Metadaten<br />
zur Laufzeit ausgewertet und die Abbildung entsprechend durchgeführt<br />
oder es wird zur Kompilierzeit expliziter Code für die Abbildung<br />
generiert. Die erste Variante verwendet üblicherweise Reflection für die Objekterzeugung<br />
und den Zugriff auf die Properties.<br />
Reflection gilt, im Verhältnis zu direkten Aufrufen, als sehr langsam,<br />
wobei dieser Overhead durch Optimierungen weitgehend elim<strong>in</strong>iert werden<br />
kann. In ausgelagerten oder anderen sicherheitskritischen Umgebungen kann<br />
Reflection e<strong>in</strong>geschränkt se<strong>in</strong>, wodurch darauf basierende Produkte nicht<br />
e<strong>in</strong>gesetzt werden können.
2. Grundlagen 15<br />
2.2.10 Weitere Aufgaben e<strong>in</strong>er O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung<br />
Zu e<strong>in</strong>er leistungsfähigen O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung gehören weitere grundlegende<br />
Funktionen. E<strong>in</strong>ige davon betreffen den Entwickler direkt, andere arbeiten<br />
unbemerkt im H<strong>in</strong>tergrund. Aus Platzgründen kann <strong>in</strong> dieser Arbeit<br />
nicht näher darauf e<strong>in</strong>gegangen werden. Der Vollständigkeit halber sollen<br />
e<strong>in</strong>ige trotzdem kurz angesprochen werden.<br />
Abfragen (Query)<br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen bieten zum<strong>in</strong>dest e<strong>in</strong>e, oft auch mehrere Möglichkeiten,<br />
Abfragen abzusetzen. Zur Anwendung kommen u. a. Abfragesprachen,<br />
die an die für Objektdatenbanken entworfene Object Query Language<br />
(OQL) [35] angelehnt s<strong>in</strong>d. Solche Abfragen werden wie <strong>in</strong> SQL als Zeichenkette<br />
übergeben.<br />
Typsichere Varianten wie das unter [FRF02, S. 316] beschriebene „Query<br />
Object“, ermöglichen Abfragekriterien als Objektgraph zu konstruieren.<br />
Seit der .<strong>NET</strong>-Version 3.5 ist die objektorientierte und typsichere Abfragesprache<br />
LINQ [31] <strong>in</strong> die .<strong>NET</strong>-Sprachen (C#, VisualBasic.<strong>NET</strong>) <strong>in</strong>tegriert.<br />
Der Trend geht dah<strong>in</strong>, dass LINQ- auch von O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen<br />
als Abfragesprache unterstützt wird.<br />
Cach<strong>in</strong>g<br />
Um das aufwändige Laden der Daten aus der Datenbank sowie das Erzeugen<br />
der Objekte zu m<strong>in</strong>imieren, werden üblicherweise verschiedene Cach<strong>in</strong>g-<br />
Strategien unterstützt. Die Palette reicht von e<strong>in</strong>em fixen <strong>in</strong>tegrierten Cache<br />
bis zu per Konfiguration e<strong>in</strong>b<strong>in</strong>dbaren Zusatzmodulen (auch von Drittherstellern)<br />
mit speziellen Cach<strong>in</strong>gstrategien, wie Unterstützung für verteilte<br />
Cache-Lösungen für Umgebungen mit mehreren Applikationsservern.<br />
Stored Procedures<br />
Der Zugriff auf die Datenbank über Stored Procedures kann u. U. durch<br />
E<strong>in</strong>sparen von Roundtrips oder Nützen RDBMS-<strong>in</strong>terner Optimierungen,<br />
Geschw<strong>in</strong>digkeitsvorteile br<strong>in</strong>gen. Es wird aber auch die Wartbarkeit von<br />
Programmen erschwert, da der Programmcode auf unterschiedliche Entwicklungsumgebungen<br />
und Programmiersprachen verteilt wird. Designentscheidungen,<br />
firmen<strong>in</strong>terne Richtl<strong>in</strong>ien oder der geme<strong>in</strong>same Zugriff auf Legacy-<br />
Datenbanken mit anderen Applikationen, die auf Stored Procedures aufsetzen,<br />
können das Zugreifen auf Stored Procedures erforderlich machen. Deshalb<br />
bieten O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen oft entsprechende Möglichkeiten an.
2. Grundlagen 16<br />
Zusammengesetzte Schlüssel<br />
Für den E<strong>in</strong>satz mit e<strong>in</strong>em O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> ist es aus verschiedenen<br />
Gründen empfehlenswert, e<strong>in</strong> Surrogat als Primärschlüssel zu verwenden<br />
(siehe auch Unterabschnitt 2.2.1). Trotzdem kann es erforderlich se<strong>in</strong>,<br />
mit zusammengesetzten Schlüsseln zu arbeiten, wenn bestehende Datenbankschemas<br />
verwendet werden müssen. E<strong>in</strong>e entsprechende Unterstützung<br />
durch die O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung sollte daher bei entsprechenden Anforderungen<br />
geprüft werden.<br />
Datenb<strong>in</strong>dung<br />
Um die aus der Datenbank geladenen Daten per Datenb<strong>in</strong>dung von Steuerelementen<br />
der Benutzeroberfläche darstellen zu lassen, s<strong>in</strong>d entsprechende<br />
Vorkehrungen zu treffen. Die Entitätsklassen können meist nach Bedarf gestaltet<br />
werden. Die gegebenenfalls notwendige Implementierung der Anforderungen<br />
des .<strong>NET</strong>-<strong>Framework</strong>s 3 , liegt daher weitgehend <strong>in</strong> der Verantwortung<br />
des Entwicklers. Die Behälterklassen werden oft vom O/R-<strong>Mapp<strong>in</strong>g</strong>-<br />
<strong>Framework</strong> vorgegeben, da sie z. B. für Laden bei Bedarf spezielle Mechanismen<br />
implementieren. Hier kann es schwierig werden, die Anforderungen<br />
des .<strong>NET</strong>-<strong>Framework</strong>s 4 zu implementieren.<br />
3-Tier bzw. n-Tier-Architektur<br />
Nicht jeder mögliche Mechanismus zum Verfolgen von Datenänderungen<br />
(change track<strong>in</strong>g) funktioniert ohne weiteres, wenn die Objekte über Prozessgrenzen<br />
h<strong>in</strong>aus übertragen werden (z. B. ASP.<strong>NET</strong> Viewstate, Client-Tier <strong>in</strong><br />
3-Tier-Applikationen). E<strong>in</strong>e Diskussion zu diesem Thema ist z. B. unter [6]<br />
zu f<strong>in</strong>den.<br />
3 z. B. INotifyPropertyChanged oder PropertyDescriptor<br />
4 z. B. ITypedList
Kapitel 3<br />
Evaluierung<br />
In diesem Abschnitt werden die für das Erstellen der Beispielapplikation<br />
relevanten Anforderungen an O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>s und deren Umsetzung<br />
<strong>in</strong> den e<strong>in</strong>zelnen Produkten (<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>, Genome<br />
und NHibernate) untersucht und deren Verwendung beschrieben.<br />
3.1 Verglichene Produkte<br />
Alle untersuchten Produkte weisen bereits e<strong>in</strong>e lange Entwicklungsgeschichte<br />
auf, auch wenn das Microsoft <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> erst vor kurzem<br />
erschienen ist. Dieser Abschnitt soll e<strong>in</strong>en E<strong>in</strong>druck davon vermitteln, wie<br />
sich die Produkte entwickelt haben und wie sie am Markt positioniert s<strong>in</strong>d.<br />
3.1.1 <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
Beim Ersche<strong>in</strong>en der .<strong>NET</strong>-Plattform von Microsoft im Jahr 2002 wurde<br />
<strong>ADO</strong>.<strong>NET</strong> und Datasets als große Neuerung und Verbesserung gegenüber<br />
<strong>ADO</strong> (Active Data Objects) angekündigt [MN02, S. 47] [RNG + 04, S. 514].<br />
Schon damals war bekannt, dass mit O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen komfortablere<br />
Möglichkeiten für die Peristierung von Objekten existieren, wobei aktuelle<br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen für .<strong>NET</strong> durchwegs auf <strong>ADO</strong>.<strong>NET</strong>, aber nicht auf<br />
Datasets aufbauen.<br />
Im Jahr 2001 wurde von Microsoft erstmals e<strong>in</strong> entsprechendes Produkt,<br />
unter der Bezeichnung ObjectSpaces, angekündigt [Esp04] [8]. Es wurde von<br />
Microsoft sogar e<strong>in</strong>e Vorabversion für <strong>in</strong>teressierte Entwickler bereitgestellt.<br />
Während im Jahr 2005 die baldige Auslieferung erwartet wurde, kündigte<br />
Microsoft an, dass ObjectSpaces zugunsten der neuen Technologie, dem<br />
<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>, LINQ 1 sowie LINQ to SQL [1,5,13,31] aufgegeben<br />
wurde. Es kamen allerd<strong>in</strong>gs e<strong>in</strong>ige Zweifel auf, ob Microsoft wirklich<br />
1 Language INtegrated Query<br />
17
3. Evaluierung 18<br />
<strong>in</strong> der Lage und auch Willens war, e<strong>in</strong>e eigene O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung zu<br />
entwickeln [Sch07].<br />
Gegen Ende des Jahres 2007 hat Microsoft als Teil des neuen .<strong>NET</strong>-<br />
<strong>Framework</strong>s Version 3.5, LINQ und LINQ to SQL ausgeliefert, wobei LINQ<br />
to SQL e<strong>in</strong>e m<strong>in</strong>imalistische O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung darstellt [Sch08]. Die<br />
Auslieferung der angekündigten flexiblen, leistungsfähigen und datenbankunabhängigen<br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>, wurde<br />
e<strong>in</strong> weiteres Mal verschoben. Im August 2008 wurde mit dem Microsoft<br />
Visual Studio 2008 Service Pack 1 und .<strong>NET</strong> <strong>Framework</strong> 3.5 Service Pack<br />
1 endlich e<strong>in</strong>e, von vielen seit Jahren erwartete, erste Version e<strong>in</strong>er O/R-<br />
<strong>Mapp<strong>in</strong>g</strong>-Lösung von Microsoft fertiggestellt und geme<strong>in</strong>sam mit anderen<br />
Neuerungen und Erweiterungen als Service Pack für Visual Studio und .<strong>NET</strong><br />
angeboten [26, 28–30, 56].<br />
Seit Microsoft Vorabversionen des <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> bereitstellt,<br />
gibt es Kritiker, die Schwächen <strong>in</strong> der Architektur und der gebotenen<br />
Funktionalität bemängeln [64]. Auch für e<strong>in</strong>en Hersteller wie Microsoft ist<br />
es unmöglich, alle Anwender vollkommen zufrieden zu stellen, doch gestehen<br />
sogar Mitglieder des Entwicklerteams Unzulänglichkeiten e<strong>in</strong> [15, 17].<br />
Die Laufzeitkomponenten des <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> s<strong>in</strong>d Teil des<br />
.<strong>NET</strong>-<strong>Framework</strong> Version 3.5 Service Pack 1, die zugehörige Entwicklungswerkzeuge<br />
s<strong>in</strong>d Teil des Service Pack 1 für Visual Studio 2008. Mit der Shared<br />
Source-Initiative [23] gewährt Microsoft für Teile des .<strong>NET</strong>-<strong>Framework</strong>s<br />
E<strong>in</strong>blick <strong>in</strong> den Quellcode. <strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> ist, zum<strong>in</strong>dest derzeit,<br />
noch davon ausgenommen.<br />
Kompetente Unterstützung bei eventuellen Problemen erhält man im<br />
MSDN-Produktforum zum <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> [18]. Im rege benutzten<br />
Forum werden viele Probleme diskutiert und mögliche Lösungen<br />
aufgezeigt. Die vorhandene Dokumentation ist leider nicht auf dem letzten<br />
Stand. Sie enthält Dokumente, die nicht vorhandene Funktionen beschreiben,<br />
oder sich auf Vorabversionen bezieht. E<strong>in</strong>e schnell größer werdende<br />
Anzahl an Bloge<strong>in</strong>trägen und anderen Onl<strong>in</strong>eressourcen zum <strong>Entity</strong> <strong>Framework</strong><br />
bieten oft die gesuchten Informationen. Weiterführende Unterstützung<br />
bietet der von Microsoft angebotene kostenpflichtige Support.<br />
Microsoft weist immer wieder darauf h<strong>in</strong>, dass die E<strong>in</strong>satzmöglichkeiten<br />
des <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> weiter reichen als die herkömmlicher<br />
O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen. Dem <strong>Entity</strong>DataReader kommt dabei laut Microsoft<br />
e<strong>in</strong>e entscheidende Bedeutung zu. Während beim herkömmlichen Data-<br />
Reader die Daten entsprechend dem Speichermodell strukturiert s<strong>in</strong>d, beziehen<br />
sich Anfragen an den <strong>Entity</strong>DataReader auf das konzeptionelle Modell.<br />
Der ausschließlich sequentielle Zugriff umgeht die Objekterzeugung durch<br />
die ObjectServices (siehe Abbildung 3.1). Die ObjectServices entsprechen<br />
dabei weitgehend der <strong>in</strong> Unterabschnitt 2.2.5 beschriebenen Arbeitse<strong>in</strong>heit.<br />
Wenn die Daten nicht als Objekte benötigt werden, wie das z. B. bei Auswertungen<br />
und Berichten der Fall se<strong>in</strong> kann, entfällt somit e<strong>in</strong> beträchtli-
3. Evaluierung 19<br />
Abbildung 3.1: <strong>Entity</strong> <strong>Framework</strong> Architektur [21].<br />
cher Verwaltungsaufwand. Die unter dem Projektnamen Astoria entwickelten<br />
<strong>ADO</strong>.<strong>NET</strong> DataServices [32, 58], stellen e<strong>in</strong>e erste Lösung dar, die das<br />
konzeptionelle Modell des <strong>Entity</strong> <strong>Framework</strong> auf diese Weise nutzen. Die<br />
<strong>ADO</strong>.<strong>NET</strong> DataServices ermöglichen den Datenbankzugriff über das HTTP<br />
Protokoll und bauen auf das <strong>Entity</strong> <strong>Framework</strong> auf. Die Daten werden als<br />
Datenstrom per HTTP übertragen. Es wäre dabei <strong>in</strong>effizient aus den Daten<br />
Objekte zu erzeugen nur um sie danach für die Übertragung zu serialisieren.<br />
3.1.2 Genome<br />
Genome [59] wurde von dem Wiener Softwarehaus TechTalk [60] entwickelt.<br />
Seit 2003 wird Genome als eigenständiges Produkt vertrieben und ist seit<br />
August 2008 <strong>in</strong> der Version 4.0 erhältlich.<br />
Bei Genome handelt es sich um e<strong>in</strong> kommerzielles Produkt, das <strong>in</strong> verschiedene<br />
Editionen zu verschiedenen Preisen angeboten wird. Die Professio-
3. Evaluierung 20<br />
nal-Edition bietet den vollständigen Funktionsumfang.<br />
E<strong>in</strong>e im Funktionsumfang etwas e<strong>in</strong>geschränkte Express Edition unterstützt<br />
grundsätzlich nur die verschiedenen Microsoft SQL-Server-Varianten,<br />
kann aber laut TechTalkfür die Unterstützung von Oracle 9i, Oracle 10g und<br />
IBM DB2 aufgerüstet werden. E<strong>in</strong>e kostenlose Community-Edition für nicht<br />
kommerzielle Softwareentwicklung, sowie e<strong>in</strong>e kostenlose Evaluation-Edition<br />
runden das Angebot ab. Der Quellcode ist über e<strong>in</strong>e entsprechende Lizenz<br />
erhältlich. Die Express-Edition, die laut TechTalk für die meisten Projekte<br />
ausreichen müsste, wird für e 299,- 2 pro Entwickler angeboten. Für die<br />
Professional-Edition liegen die Preise zwischen e 1.170,- und e 1.800,- pro<br />
Entwickler, gestaffelt nach Anzahl der erworbenen Lizenzen. Zu beziehen ist<br />
Genome entweder direkt von TechTalk oder über Vertriebspartner.<br />
Für diese Arbeit wurde von TechTalk freundlicherweise e<strong>in</strong>e Lizenz für<br />
die Community-Edition mit der Laufzeit von e<strong>in</strong>em Jahr zur Verfügung gestellt.<br />
Die Community-Edition entspricht vom Funktionsumfang der Professional-Edition.<br />
Für die erstellte Beispielanwendung wird nur Funktionalität<br />
genutzt, die auch von der Express-Edition geboten wird.<br />
Für die aktuelle Version 4.0 wird .<strong>NET</strong> 3.5 und Visual Studio 2008 vorausgesetzt,<br />
Vorgängerversionen arbeitet auch mit den früheren .<strong>NET</strong>- und<br />
Visual Studio-Versionen zusammen.<br />
Für Fragen wurde e<strong>in</strong>ige Male auf das kostenlose Support-Forum zurückgegriffen,<br />
das über die Genome-Webseite erreichbar ist. Die Antworten<br />
erfolgten durchwegs <strong>in</strong>nerhalb weniger Stunden und waren kompetent und<br />
ausführlich. Die Dokumentation ist umfangreich, wurde aber für diese Arbeit<br />
zu wenig benötigt, um sie beurteilen zu können.<br />
3.1.3 NHibernate<br />
NHibernate [KBK08] [46] ist e<strong>in</strong>e Portierung der für Java entwickelten und<br />
sehr populären O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösung Hibernate [KB04, Bau06] [41] auf die<br />
.<strong>NET</strong>-Plattform. Hibernate wurde von Gav<strong>in</strong> K<strong>in</strong>g als quelloffenes Projekt<br />
<strong>in</strong>itiiert [62]. Auf SourceForge.net reichen die Informationen bis zur Version<br />
0.8 im Dezember 2001 zurück [61]. Gav<strong>in</strong> K<strong>in</strong>g wurde später von der Firm<br />
JBoss [44], das mittlerweile zu RedHat [45] gehört, angestellt, um Hibernate<br />
weiterzuentwickeln [65]. Tom Barret begann, ausgehend von der Version<br />
2.1, Hibernate nach .<strong>NET</strong> zu portieren [3]. Erste E<strong>in</strong>träge dazu f<strong>in</strong>den sich<br />
ebenfalls auf SourceForge.net, datiert mit März 2003. Später wurden auch<br />
führende NHibernate-Entwickler von JBoss angestellt, um die weitere Entwicklung<br />
hauptberuflich zu betreiben [3].<br />
Im August 2008 wurde die NHibernate-Version 2.0 freigegeben, die vom<br />
Funktionsumfang weitgehend Hibernate 3.2 entsprechen soll. LINQ-Support<br />
für NHibernate ist schon längere Zeit <strong>in</strong> Arbeit und wird für die nächs-<br />
2 Auf der Webseite ausgewiesene Listenpreise
3. Evaluierung 21<br />
te Version erwartet [43]. Für aktuelle NHibernate-Versionen ist .<strong>NET</strong> 2.0<br />
M<strong>in</strong>destvoraussetzung. Weiters soll NHibernate auch mit der quelloffenen<br />
.<strong>NET</strong>-Implementierung Mono [33] zusammenarbeiten.<br />
<strong>Das</strong>s NHibernate von vielen Entwicklern e<strong>in</strong>gesetzt wird, ist an der Anzahl<br />
an E<strong>in</strong>trägen <strong>in</strong> verschiedensten Foren und Blogs zu erkennen. Für die<br />
meisten auftretenden Fragen und Probleme s<strong>in</strong>d daher bereits Antworten<br />
vorhanden. Die große Anzahl an E<strong>in</strong>trägen erschwert es oft, zu konkreten<br />
Problemen die passenden E<strong>in</strong>träge auch zu f<strong>in</strong>den. Die Dokumentation ist<br />
für e<strong>in</strong>e quelloffenes Produkt umfangreich und weitgehend leicht zu verstehen.<br />
Professioneller Support für NHibernate wird von RedHat angeboten.<br />
3.2 Funktionalität<br />
3.2.1 Metadaten<br />
Bei allen drei Testkandidaten muss dem O/R-<strong>Mapp<strong>in</strong>g</strong>-Framwork mittels<br />
Metadaten (siehe Unterabschnitt 2.1.3) vorgegeben werden, welche Klassen<br />
für die Persistierung vorgesehen s<strong>in</strong>d und wie diese Klassen und ihre Beziehungen<br />
untere<strong>in</strong>ander behandelt werden sollen. Beim <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong><br />
<strong>Framework</strong> und bei NHibernate werden diese Informationen grundsätzlich<br />
erst zu Laufzeit benötigt. Die Metadaten können zur Laufzeit, vor der Weitergabe<br />
an das O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>, generiert und auch manipuliert<br />
werden. <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> kann aus den Metadaten den Quelltext<br />
für die Entitätsklassen automatisch generieren, auch dafür müssen die<br />
Metadaten bereits zur Entwicklungszeit vorliegen. Genome generiert aus<br />
den Metadaten Quelltext, der die Persistierung und Wiederherstellung der<br />
Objekte vornimmt und benötigt die Metadaten daher zw<strong>in</strong>gend zur Entwicklungszeit.<br />
Genome und das <strong>Entity</strong> <strong>Framework</strong> validieren die Metadaten<br />
schon zur Übersetzungszeit, bei NHibernate treten eventuelle Fehler erst zur<br />
Laufzeit zu Tage.<br />
Alle untersuchten Produkte erwarten die Metadaten im XML-Format.<br />
NHibernate ermöglicht, die E<strong>in</strong>bettung der Metadaten als Attribute <strong>in</strong> die<br />
Entitätsklassen, aus denen zur Laufzeit das geforderte XML-Format generiert<br />
wird. NHibernate und Genome benötigen für jede zu persistierende<br />
Entitätsklasse <strong>in</strong> den Metadaten e<strong>in</strong> Element, das def<strong>in</strong>iert, wie diese Klasse<br />
und die Beziehungen abgebildet werden sollen. Die Metadaten können<br />
auf mehrere Dateien aufgeteilt werden, wobei e<strong>in</strong>e Datei e<strong>in</strong>en oder mehrere<br />
Elemente enthalten kann. Beim <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> wurde hier<br />
e<strong>in</strong> abweichender Ansatz gewählt.<br />
Die Metadaten des <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> bestehen aus drei Teilen,<br />
die geme<strong>in</strong>sam das <strong>Entity</strong> Data Model (EDM) bilden [Pap07] [20,25,27].<br />
E<strong>in</strong> Teil, das Konzeptionelle Modell (Conceptual Schema), beschreibt die<br />
Struktur der Entitätsklassen und deren Beziehungen untere<strong>in</strong>ander. <strong>Das</strong><br />
Speichermodell (Storage Schema), gibt die Struktur des Datenbankschemas
3. Evaluierung 22<br />
wider. Die Abbildungsdef<strong>in</strong>ition (<strong>Mapp<strong>in</strong>g</strong> Specification) ist der dritte Teil,<br />
der beschreibt, wie das konzeptionelle Modell auf das Speichermodell abgebildet<br />
wird. <strong>Das</strong> <strong>Entity</strong> Data Model wird zusammen mit Daten für das<br />
grafische Designer-Werkzeug <strong>in</strong> e<strong>in</strong>er Datei mit der Endung .edmx abgelegt.<br />
List<strong>in</strong>g 3.1 bis List<strong>in</strong>g 3.5 zeigen die Teile e<strong>in</strong>er m<strong>in</strong>imalistischen edmx-Datei,<br />
mit der e<strong>in</strong>e e<strong>in</strong>zelne Klasse „Country“ ohne Beziehungen abgebildet wird.<br />
List<strong>in</strong>g 3.1 zeigt dabei das Gerüst, das die e<strong>in</strong>zelnen Abschnitte umgibt. In<br />
List<strong>in</strong>g 3.2 bis List<strong>in</strong>g 3.4 s<strong>in</strong>d diese Abschnitte der Metadaten dargestellt.<br />
Diese drei Abschnitte s<strong>in</strong>d ähnlich strukturiert. <strong>Das</strong> konzeptionelle Modell<br />
sowie das Speichermodell enthalten jweils e<strong>in</strong>e Def<strong>in</strong>ition für e<strong>in</strong>en <strong>Entity</strong>-<br />
Conta<strong>in</strong>er, der e<strong>in</strong>er Arbeitse<strong>in</strong>heit (siehe Unterabschnitt 2.2.5 entspricht.<br />
Der <strong>Entity</strong>Conta<strong>in</strong>er enthält <strong>Entity</strong>Set- und AssociationSet-Def<strong>in</strong>itionen,<br />
die im Speichermodell den Tabellen und referentiellen Beziehungen zwischen<br />
den Tabellen entsprechen, im konzeptionellen Modell jedoch den Entitätsklassen<br />
entsprechen. AssociationSet-Def<strong>in</strong>itionen kommen <strong>in</strong> den angeführten<br />
Quelltexten nicht vor, da ke<strong>in</strong>e Beziehungen def<strong>in</strong>iert wurden. In der Abbildungsdef<strong>in</strong>ition<br />
wwerden über <strong>Entity</strong>Conta<strong>in</strong>er<strong>Mapp<strong>in</strong>g</strong>, <strong>Entity</strong>Set<strong>Mapp<strong>in</strong>g</strong><br />
und AssociationSet<strong>Mapp<strong>in</strong>g</strong> die Elemente aus dem konzeptionellen Modell<br />
den entsprechenden Elementen aus dem Speichermodell zugeordnet. Die<br />
<strong>Entity</strong>Type-Def<strong>in</strong>itionen geben die Struktur der Tabellen und Entitätsklassen<br />
wider, auf die sich die <strong>Entity</strong>Set-Def<strong>in</strong>itionen im konzeptionellen sowie<br />
im Speichermodelle beziehen. Die <strong>Entity</strong>Type<strong>Mapp<strong>in</strong>g</strong>-Elemente <strong>in</strong> der Abbildungsdef<strong>in</strong>ition<br />
legen wiederum fest welche <strong>Entity</strong>Type-Elemente aus dem<br />
konzeptionellen Modell auf welche <strong>Entity</strong>Type-Elemente im Speichermodell<br />
abgebildet werden. Für die Def<strong>in</strong>ition des <strong>Entity</strong>DataModel stehen noch e<strong>in</strong>ige<br />
weitere Elemente zur Verfügung, etwa um Vererbung festzulegen. Beispielhafte<br />
Daten des Designer-Werkzeugs werden <strong>in</strong> List<strong>in</strong>g 3.5 gezeigt.<br />
List<strong>in</strong>g 3.1: <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> edmx-Datei.<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
Zur Laufzeit müssen die Metadaten als drei eigenständige XML-Dateien, mit<br />
den Endungen .csdl 3 , .ssdl 4 und .msl 5 vorliegen. Beim Übersetzen werden<br />
3 Conceptual Schema Def<strong>in</strong>ition Language<br />
4 Storage Schema Def<strong>in</strong>ition Language<br />
5 <strong>Mapp<strong>in</strong>g</strong> Specification Language
3. Evaluierung 23<br />
diese Dateien aus der .edmx-Datei generiert [11].<br />
List<strong>in</strong>g 3.2: Der „CSDL content“ aus List<strong>in</strong>g 3.1, Zeile 6.<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
12 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17 <br />
List<strong>in</strong>g 3.3: Der „SSDL content“ aus List<strong>in</strong>g 3.1, Zeile 5.<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
12 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17
3. Evaluierung 24<br />
List<strong>in</strong>g 3.4: Der „C-S mapp<strong>in</strong>g content“ aus List<strong>in</strong>g 3.1, Zeile 7.<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
12 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17 <br />
List<strong>in</strong>g 3.5: Ausschnitt „EF Designer content“ aus List<strong>in</strong>g 3.1, Zeile 9.<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
12 <br />
13 <br />
14 <br />
15 <br />
16 <br />
17 <br />
Bei Genome und NHibernate werden diese Metadaten wesentlich kompakter<br />
dargestellt. So haben die Metadaten für das <strong>Entity</strong> <strong>Framework</strong> <strong>in</strong> der<br />
erstellten Beispielanwendung <strong>in</strong> etwa den dreifachen Umfang im Vergleich
3. Evaluierung 25<br />
zu den anderen beiden Produkten. Derselbe Anwendungsfall, den List<strong>in</strong>g 3.1<br />
bis List<strong>in</strong>g 3.5 für das <strong>Entity</strong> <strong>Framework</strong> dargestellen, wird für NHibernate<br />
mit List<strong>in</strong>g 3.6 bzw. für Genome mit List<strong>in</strong>g 3.7 umgesetzt. Für jede Entitätsklasse<br />
die persitiert werden soll, wird e<strong>in</strong> class-Element erstellt. Mit<br />
e<strong>in</strong>em Attribut wird der Name der Tabelle festgelegt werden, <strong>in</strong> die die<br />
Entitätsklasse persistiert werden soll. S<strong>in</strong>d Tabellenname und Klassenname<br />
identisch wie im angeführten Beispiel, kann diese Angabe entfallen. <strong>Das</strong><br />
id-Element def<strong>in</strong>iert das Id-Attribut bzw. den Primärschlüssel(siehe Unterabschnitt<br />
2.2.1). Mit dem version-Element wird e<strong>in</strong>e Property für optimistische<br />
verb<strong>in</strong>dungslose Sperre (siehe Unterabschnitt 2.2.6) festgelegt. Die<br />
Abbildung e<strong>in</strong>zelner Properties der Entitätsklassen auf Attribute der Tabellen<br />
erfolgt über property-Elemente, wobei die Namen der Tabellenattribute<br />
nur anzugeben s<strong>in</strong>d, wenn diese von den Propertynamen abweichen.<br />
List<strong>in</strong>g 3.6: NHibernate Metadaten.<br />
1 <br />
2 <br />
7<br />
8 <br />
11 <br />
15 <br />
16 RowId<br />
17 NextValue<br />
18 10<br />
19 <br />
20 <br />
21<br />
22 <br />
25<br />
26 <br />
30<br />
31 <br />
35 <br />
36
3. Evaluierung 26<br />
Die Metadaten s<strong>in</strong>d bei Genome ähnlich strukturiert wie bei NHibernate.<br />
Die Elemente Type, PrimaryKey, OptimisticLock und Member <strong>in</strong> Genome<br />
entsprechen <strong>in</strong> etwa den NHibernate-Elementen class, id, version und property.<br />
<strong>Das</strong> Element CodeGeneratedProxy weist Genome an, zu den abstrakten<br />
Entitätsklassen Quelltext für konkrete Implementierungen zu generieren.<br />
Es ist bei allen Entitätsklassen anzugeben, außer es handelt sich um abstrakte<br />
Basisklassen von denen ke<strong>in</strong>e Objekte erzeugt werden sondern von denen<br />
nur weiter abgeleitet wird, wie das z. B. bei den Klassen Item oder Contact<br />
<strong>in</strong> der Beispielimplementierung der Fall ist (siehe Kapitel 4).<br />
List<strong>in</strong>g 3.7: Genome Metadaten<br />
1 <br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9<br />
10 <br />
11<br />
12 <br />
13 <br />
14 <br />
15 Id<br />
16 <br />
17 <br />
18 <br />
19 <br />
20<br />
21 <br />
22 <br />
23 <br />
24 <br />
25 <br />
26 <br />
27 <br />
28 <br />
29 <br />
30 <br />
31 <br />
3.2.2 Objektidentität<br />
Wie im Unterabschnitt 2.2.1 beschrieben s<strong>in</strong>d e<strong>in</strong>fache künstliche Schlüssel,<br />
die per Sequence-Mechanismus generiert werden, e<strong>in</strong>e effiziente Lösung zum<br />
Erzeugen von Ids für neue Objekte. Noch effizienter können GUID-Werte
3. Evaluierung 27<br />
generiert werden, da das ohne jeden Datenbankzugriff erfolgen kann. Ids<br />
vom Typ GUID haben aber den Nachteil, dass sie wesentlich mehr Speicherplatz<br />
(16 Bytes) benötigen und dadurch die Indizes vergrößern (siehe<br />
Unterabschnitt 2.2.1). Alle drei untersuchten Produkte können laut Dokumentation,<br />
GUID als Primärschlüssel ohne weiteres handhaben. Da <strong>in</strong> der<br />
Beispielanwendung ke<strong>in</strong>e besonderen Anforderungen die Verwendung von<br />
GUID rechtfertigen, ist die Wahl auf den Sequence-Mechanismus gefallen,<br />
der nachfolgend näher untersucht wird.<br />
NHibernate unterstützt, abhängig vom e<strong>in</strong>gesetzten RDBMS, mehrere<br />
Varianten. Bei Datenbanken wie z. B. Oracle, die selbst e<strong>in</strong>en Sequence-<br />
Mechanismus anbieten, kann NHibernate angewiesen werden, diesen zu verwenden.<br />
Andernfalls genügt es, e<strong>in</strong>e Tabelle mit e<strong>in</strong>em Attribut <strong>in</strong> der Datenbank<br />
anzulegen, die NHibernate zur Verfügung gestellt wird, um den nächsten<br />
verfügbaren Wert abzulegen. Letztere Variante wurde <strong>in</strong> der Beispielanwendung<br />
genutzt, da der Microsoft SQL-Server ke<strong>in</strong>en Sequence-Mechanismus<br />
anbietet. Diese Variante bietet höchstmögliche Portabilität, da sie auf<br />
jedes RDBMS identisch abgebildet werden kann. Neben der Effizienz ist das<br />
e<strong>in</strong> weiterer wesentliche Vorteil.<br />
List<strong>in</strong>g 3.8: NHibernate Beispiel<br />
1 <br />
4 <br />
8 <br />
9 RowId<br />
10 NextValue<br />
11 10<br />
12 <br />
13 <br />
14 <br />
15 <br />
List<strong>in</strong>g 3.8 zeigt, wie die gewünschte Id-Generierungsvariante <strong>in</strong> NHibernate<br />
festgelegt wird, die relevanten XML-Elemente s<strong>in</strong>d durch Fettdruck<br />
hervorgehoben. Die ID-Generierung ist für jede abzubildende Klasse e<strong>in</strong>zeln<br />
festzulegen. Der Generierungsalgorithmus heißt <strong>in</strong> NHibernate „hilo“.<br />
RowId ist der Name der zu verwendenden Tabelle, NextValue der Name<br />
des Attributes <strong>in</strong> der Tabelle. Die Anzahl der Werte, die bei jedem Zugriff<br />
angefordert werden, wird mit Parameter max_lo festgelegt. Ohne explizite<br />
Def<strong>in</strong>ition von table, column und max_lo werden von NHibernate bereitgestellte<br />
Vorgabewerte verwendet. E<strong>in</strong>e Schwäche dieser Implementierung<br />
ist, dass für jede Klasse e<strong>in</strong> eigener Zähler im Speicher verwaltet wird. Die<br />
Anzahl verlorener Werte wird dadurch unnötig erhöht.
3. Evaluierung 28<br />
Per Konfiguration bietet <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> die Auswahl zwischen<br />
vier Varianten, um Id-Werte zu generieren. Bei zwei der vier Varianten<br />
wird erwartet, dass die Werte <strong>in</strong> der Datenbank erzeugt werden. Entweder<br />
ist der Primärschlüssel als e<strong>in</strong> Attribut des Typs Identity def<strong>in</strong>iert oder die<br />
Werte des Primärschlüssels werden auf e<strong>in</strong>e andere Art <strong>in</strong> der Datenbank<br />
zugewiesen, z. B. durch Trigger. Wird für den Primärschlüssel der Datentyp<br />
GUID gewählt, übernimmt das <strong>Entity</strong> <strong>Framework</strong> die automatische Zuweisung<br />
neuer Werte. Als vierte Variante wird angeboten, dass sich das <strong>Entity</strong><br />
<strong>Framework</strong> nicht um die Generierung kümmert. Damit wird zum<strong>in</strong>dest e<strong>in</strong>e<br />
eigene Implementierung von Clientseitig zugewiesenen Id-Werten ermöglicht.<br />
Für die Beispielanwendung wurde die letzte Variante gewählt, die den<br />
Sequence-Mechanismus nachbildet, wie <strong>in</strong> Unterabschnitt 2.2.1 beschrieben.<br />
Diese Lösung entspricht <strong>in</strong> etwa dem bei NHibernate verwendetem HiLo-<br />
Algorithmus. Die konkrete Realisierung ist unter Unterabschnitt 4.2.3 detaillierter<br />
ausgeführt.<br />
Trotz der bekannten Nachteile von GUID und datenbankgenerierten Primärschlüsseln<br />
wird der Sequence-Mechanismus vom <strong>Entity</strong> <strong>Framework</strong> nicht<br />
unmittelbar unterstützt. Die eigene, wiederverwendbare Implementierung,<br />
besteht nur aus wenigen Zeilen Quellcode, aber gerade dieser Umstand ließe<br />
erwarten, dass diese Variante als fixer Bestandteil e<strong>in</strong>es <strong>Framework</strong>s bereitgestellt<br />
wird. Auch wenn die eigene Implementierung nur aus wenigen Zeilen<br />
besteht, waren doch fortgeschrittene Kenntnisse für die Implementierung erforderlich.<br />
Konkrete H<strong>in</strong>weise dazu fanden sich <strong>in</strong> der Dokumentation nicht.<br />
Die Situation bei Genome entspricht weitgehend der beim <strong>Entity</strong> <strong>Framework</strong>.<br />
Wird Oracle als Datenbank verwendet, steht als zusätzliche Variante<br />
Sequence zur Verfügung. Da die Beispielanwendung auch mit dem Microsoft<br />
SQL-Server zusammenarbeiten soll, wurde wie beim <strong>Entity</strong> <strong>Framework</strong><br />
e<strong>in</strong>e eigene Lösung zum Nachbilden des Sequence-Mechanismus erstellt. Die<br />
Umsetzung war mit noch etwas weniger Quellcode zu realisieren und mit<br />
Grundkenntnissen <strong>in</strong> ca. fünf Stunden zu schaffen. Trotzdem wäre auch hier<br />
e<strong>in</strong>e <strong>in</strong>tegrierte Lösung wünschenswert.<br />
3.2.3 Beziehungen<br />
Grundsätzlich können mit allen drei Produkten alle <strong>in</strong> Unterabschnitt 2.2.2<br />
beschriebenen Beziehungen def<strong>in</strong>iert werden. Beim <strong>Entity</strong> <strong>Framework</strong> s<strong>in</strong>d<br />
alle Beziehungen automatisch bidirektional. Unidirektionale Beziehungen<br />
werden nicht unterstützt. Genome und NHibernate bieten nur unidirektionale<br />
Beziehungen, bidirektionale Beziehungen werden aus zwei unidirektionalen<br />
Beziehungen aufgebaut.<br />
Ob beim Löschen e<strong>in</strong>es Datensatzes, der Detaildatensätze enthält, das<br />
Löschen verh<strong>in</strong>dert werden soll oder ob <strong>in</strong> diesem Fall auch die Detaildatensätze<br />
automatisch gelöscht werden sollen, kann bei NHibernate und beim<br />
<strong>Entity</strong> <strong>Framework</strong> <strong>in</strong> den Metadaten def<strong>in</strong>iert werden. Bei Genome ist dafür
3. Evaluierung 29<br />
e<strong>in</strong>e Ereignismethode <strong>in</strong> der Entitätsklasse zu implementieren, die das Löschen<br />
gegebenenfalls verh<strong>in</strong>dert bzw. vorhandene Detaildatensätze explizit<br />
löscht. List<strong>in</strong>g 3.9 zeigt e<strong>in</strong>e entsprechende Implementierung aus der Klasse<br />
PurchOrder. Die Klasse muss das Interface IDeleteCallback implementieren.<br />
List<strong>in</strong>g 3.9: Genome: Bestellpositionen automatisch mit der Bestellung löschen.<br />
1 #region IDeleteCallback Members<br />
2<br />
3 public void OnDelete()<br />
4 {<br />
5 foreach (PurchOrderL<strong>in</strong>e ol <strong>in</strong> OrderL<strong>in</strong>es)<br />
6 Context.GetEffectiveContext(this).Delete(ol);<br />
7 }<br />
8<br />
9 #endregion<br />
Für den Zugriff auf <strong>in</strong> Beziehung stehende Datensätze über entsprechende<br />
Datenkomponenten der Enitätsklassen gibt es verschiedene Strategien.<br />
Entweder müssen die Daten explizit vor dem ersten Zugriff aus der Datenbank<br />
geladen werden, wie es beim <strong>Entity</strong> <strong>Framework</strong> der Fall ist, oder<br />
sie werden beim ersten Zugriff automatisch nachgeladen (Laden bei Bedarf,<br />
siehe Unterabschnitt 2.2.7). Die zweite Variante kommt bei Genome zum<br />
E<strong>in</strong>satz. E<strong>in</strong>e weitere mögliche Variante ist, referenzierte Daten sofort mitzuladen,<br />
entweder <strong>in</strong> e<strong>in</strong>er Jo<strong>in</strong>-Abfrage oder <strong>in</strong> zwei aufe<strong>in</strong>ander folgenden<br />
Befehlen, auch gieriges Laden (Greedy Load<strong>in</strong>g) genannt. Nur bei NHibernate<br />
kann jede dieser Varianten, für jede Beziehung <strong>in</strong>dividuell, <strong>in</strong> den Metadaten<br />
def<strong>in</strong>iert werden. Alle drei Produkte bieten noch die Möglichkeit,<br />
<strong>in</strong> e<strong>in</strong>er Abfrage festzulegen, welche Beziehungen automatisch sofort mitgeladen<br />
werden sollen. Die entsprechenden Anweisungen heißen bei Genome<br />
PreCache, bei <strong>Entity</strong> <strong>Framework</strong> Include und bei NHibernate Fetch bzw.<br />
SetFetchMode. Bei Genome können die <strong>in</strong> Beziehung stehenden Datensätze,<br />
die nachgeladen werden sollen, über e<strong>in</strong>fache oder komplexe Kriterien zusätzlich<br />
e<strong>in</strong>geschränkt werden. Für Laden bei Bedarf müssen bei NHibernate<br />
und Genome die mit den Produkten gelieferten Behälterklassen verwendet<br />
werden.<br />
Microsoft unterscheidet bei Laden bei Bedarf zwischen implizitem und<br />
explizitem Laden bei Bedarf [16]. <strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> unterstützt nur<br />
explizites Laden bei Bedarf. Vor dem ersten Zugriff muss die Methode Load<br />
aufgerufen werden. Beim impliziten Laden bei Bedarf, wie es NHibernate<br />
und Genome unterstützen, wird dieser Aufruf bei Bedarf automatisch<br />
ausgeführt. <strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> unterstützt implizites Laden bei Bedarf<br />
nicht, was auch häufig kritisiert wird [64]. Mitglieder des <strong>Entity</strong> <strong>Framework</strong>-<br />
Entwicklungsteams stellen <strong>in</strong> Aussicht, implizites Laden bei Bedarf <strong>in</strong> e<strong>in</strong>er<br />
späteren Version zu implementieren [14, 17].
3. Evaluierung 30<br />
3.2.4 E<strong>in</strong>gebetteter Wert<br />
Diese <strong>in</strong> Unterabschnitt 2.2.3 beschriebene Möglichkeit, Klassen auf Tabellen<br />
abzubilden, wird nur von NHibernate ausreichend unterstützt. Bei Genome<br />
sowie beim <strong>Entity</strong> <strong>Framework</strong> wird dieser Mechanismus grundsätzlich angeboten,<br />
jedoch mit der E<strong>in</strong>schränkung, dass diese e<strong>in</strong>gebetteten Klassen<br />
ke<strong>in</strong>e Beziehungen zu weiteren Entitäten be<strong>in</strong>halten dürfen. Schon e<strong>in</strong>fache<br />
Beispiele, die <strong>in</strong> diesem Zusammenhang genannt werden, wie Geldbeträge<br />
[FRF02, S. 268] oder Adressen, können damit nicht richtig abgebildet<br />
werden. Bei e<strong>in</strong>em Geldbetrag wird e<strong>in</strong>e Beziehung zur Währung, bei<br />
Adresse zum<strong>in</strong>dest e<strong>in</strong>e Beziehung zu Land benötigt. Umgangen kann diese<br />
E<strong>in</strong>schränkung bei Genome und dem <strong>Entity</strong> <strong>Framework</strong> werden, <strong>in</strong>dem nur<br />
die Abbildung der Fremdschlüssel-Attribute (z. B. CurrencyId bzw. CountryId)<br />
ohne die zugehörigen Beziehungen def<strong>in</strong>iert werden. Def<strong>in</strong>iert wird<br />
e<strong>in</strong>gebetteter Wert <strong>in</strong> NHibernate mit dem XML-Element Component, beim<br />
<strong>Entity</strong> <strong>Framework</strong> mit ComplexType. EmbeddedStruct ist das entsprechende<br />
XML-Element bei Genome, obwohl damit auch Klassen e<strong>in</strong>gebettet werden<br />
können.<br />
3.2.5 Vererbung<br />
Von allen Testkandidaten werden alle drei möglichen Vererbungs-Varianten<br />
(siehe Unterabschnitt 2.2.4) unterstützt. Genome benötigt, im Gegensatz<br />
zum <strong>Entity</strong> <strong>Framework</strong> und zu NHibernate, auch bei Vererbung mit e<strong>in</strong>er<br />
Tabelle pro Klasse e<strong>in</strong> Diskrim<strong>in</strong>ator-Attribut.<br />
Über das grafische Designer-Werkzeug des <strong>Entity</strong> <strong>Framework</strong> kann nur<br />
die Variante „Vererbungshierarchie <strong>in</strong> e<strong>in</strong>er Tabelle“ def<strong>in</strong>iert werden. Die<br />
beiden alternativen Varianten können, durch manuelles Anpassen des XML-<br />
Quelltextes <strong>in</strong> der edmx-Datei, def<strong>in</strong>iert werden, wobei das manuelle Bearbeiten<br />
besonders erschwert wird, da die e<strong>in</strong>zelnen XML-Elemente, die e<strong>in</strong>e<br />
Vererbung def<strong>in</strong>ieren, über das gesamte <strong>Entity</strong> Data Model verteilt s<strong>in</strong>d und<br />
Vererbung nicht explizit über entpsrechende Elemente ausgedrückt wird. Die<br />
Vergleichsprodukte weisen zum<strong>in</strong>dest „Vererbungshierarchie <strong>in</strong> e<strong>in</strong>er Tabelle“<br />
und „Vererbung mit e<strong>in</strong>er Tabelle pro Klasse“ durch spezielle XML-<br />
Elementen aus. Bei NHibernate s<strong>in</strong>d dies subclass und jo<strong>in</strong>ed-subclass, bei<br />
Genome SharedInheritance und Jo<strong>in</strong>edInheritance.<br />
3.2.6 Nebenläufigkeit<br />
<strong>Das</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> unterstützt nur optimistische verb<strong>in</strong>dungslose<br />
Sperren (Optimistic Offl<strong>in</strong>e Lock) [24]. NHibernate und Genome<br />
bieten dagegen auch pessimistitsche Sperren (Pessimistic Lock), also Sperren,<br />
die auf Datenbankebene gesetzt werden (siehe Unterabschnitt 2.2.6).<br />
Alle drei Produkte können bei optimistischer verb<strong>in</strong>dungsloser Sperre<br />
e<strong>in</strong>e beliebige Auswahl an Attributen e<strong>in</strong>er Tabelle zur Konflikterkennung
3. Evaluierung 31<br />
heranziehen. Die effizienteste Lösung besteht allerd<strong>in</strong>gs dar<strong>in</strong>, nur e<strong>in</strong> Attribut<br />
als Datensatzversion zu verwenden. Der Microsoft SQL-Server bietet<br />
speziell für diesen Zweck den Datentyp Timestamp. Um die Portabilität<br />
nicht unnötig e<strong>in</strong>zuschränken, wurde für die Beispielanwendung jedoch e<strong>in</strong><br />
Ganzzahliges Versionsattribut verwendet.<br />
NHibernate bietet hier die e<strong>in</strong>fachste Lösung. Es genügt, <strong>in</strong> der Konfiguratonsdatei<br />
e<strong>in</strong>e Property der Klasse für die Konflikterkennung zu Kennzeichnen.<br />
NHibernate erkennt am Datentyp automatisch, ob es den Wert<br />
beim Speichern von Änderungen erhöhen muss, oder ob das Attribut von<br />
der Datenbank aktualisiert wird.<br />
Wird der Datentyp Timestamp für das Versionsattribut verwendet, ist<br />
auch beim <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> die Konfiguration ähnlich unkompliziert.<br />
Soll der Datentyp Ganzzahl verwendet werden, ist der Entwickler<br />
für das Erhöhen des Wertes beim Speichern zuständig. Die Implementierung<br />
ist, wie beim Sequence-Mechanismus, mit wenigen Zeilen Quellcode zu<br />
realisieren, aber für E<strong>in</strong>steiger nicht unbend<strong>in</strong>gt naheliegend (siehe Unterabschnitt<br />
4.2.6).<br />
Genome akzeptiert bei Verwendung des Microsoft SQL-Server nur den<br />
Datentyp Timestamp für das Versionsattribut, obwohl <strong>in</strong> Zusammenarbeit<br />
mit Oracle der Datentyp Ganzzahl dafür unterstützt wird. Die Portabilität<br />
wird dadurch unnötig e<strong>in</strong>geschränkt. Im Supportforum wurde auf Anfrage<br />
e<strong>in</strong> Lösungsansatz geschildert, wie auch mit dem SQL-Server der Ganzzahl-<br />
Datentyp für das Versionsattribut verwendet werden kann, der aber zu komplex<br />
erschien, um ihn im Zuge dieser Arbeit umzusetzen. Für die Genome-<br />
Beispielapplikation wurde deshalb der Datentyp Timestamp verwendet, wodurch<br />
e<strong>in</strong>e eigenes, entsprechend abweichendes Datenbankschema erstellt<br />
werden musste. Weiters muss bei Genome jede Sperre für jedes Objekt explizit<br />
gesetzt werden.<br />
3.2.7 Abfragen<br />
OQL<br />
Alle drei Testkandidaten bieten mehrere Möglichkeiten, Abfragen gegen das<br />
konzeptionelle Modell abzusetzen. E<strong>in</strong>e an OQL angelehnte Abfragesprache,<br />
die als Zeichenkette übergeben wird, wie <strong>in</strong> Unterabschnitt 2.2.10 beschrieben,<br />
bieten alle untersuchten Produkten. Bei NHibernate wird sie HQL (Hibernate<br />
Query Languag), bei Genome OQL (Object Query Language) und<br />
beim <strong>Entity</strong> <strong>Framework</strong> eSQL bzw. <strong>Entity</strong>-SQL bezeichnet.<br />
LINQ<br />
<strong>Das</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> bietet schon seit den ersten Testversionen<br />
LINQ-Unterstützung. Für Genome ist diese Abfragevariante seit e<strong>in</strong>igen
3. Evaluierung 32<br />
Monaten verfügbar und dürfte bereits stabil se<strong>in</strong>. NHibernate h<strong>in</strong>kt den beiden<br />
anderen Testkandidaten diesbezüglich noch deutlich h<strong>in</strong>terher. Für die<br />
im August veröffentlichte Version 2.0 wurde die LINQ-Unterstützung nicht<br />
rechtzeitig fertig. Über e<strong>in</strong>en möglichen Zeitpunkt der Fertigstellung wurde<br />
noch nichts bekannt gegeben.<br />
SQL<br />
NHibernate und Genome bietet noch zusätzlich die Möglichkeit, SQL als<br />
Abfragesprache zu nutzen. Da mit diesem Mechanismus die Abstraktion<br />
der Datenbank aufgeweicht wird, sollte genau abgewogen werden, ob e<strong>in</strong><br />
konkreter Anwendungsfall diese E<strong>in</strong>schränkung rechtfertigt.<br />
3.3 Softwarearchitektur<br />
3.3.1 Unabhängigkeit der Entitätsklassen von der Persistenzschicht<br />
(Persistence Ignorance)<br />
Jede O/R-<strong>Mapp<strong>in</strong>g</strong>-Lösungen schränkt die Freiheit beim Entwurf der Entitätsklassen<br />
<strong>in</strong> gewissem Masse e<strong>in</strong>. So setzen alle Produkte e<strong>in</strong>e ID-Property<br />
<strong>in</strong> den Entitätsklassen voraus, um die Objekte im Speicher e<strong>in</strong>deutig den<br />
persistierten Datensätzen zuordnen zu können.<br />
Bei Genome müssen die Entitätsklassen abstrakte Klassen se<strong>in</strong>. Genome<br />
generiert zur Übersetzungszeit automatisch Quelltext für die dazugehörige<br />
konkrete Implementierung. Die Objekterzeugung muss deshalb an das<br />
<strong>Framework</strong> delegiert werden. E<strong>in</strong> Vorteil dieser Vorgangsweise ist, dass Methoden<br />
zum H<strong>in</strong>zufügen und Entfernen von Detaildatensätzen automatisch<br />
generiert werden. E<strong>in</strong> Konstruktor, der alle <strong>in</strong> den Metadaten dieser Entität<br />
def<strong>in</strong>ierten Properties als Parameter akzeptiert, muss aber für jede<br />
Klasse manuell implementiert werden. Es wird empfohlen, Entitätsklassen<br />
von TechTalk.Genome.Persistent abzuleiten, da dar<strong>in</strong> die Vergleichsoperatoren<br />
überschrieben s<strong>in</strong>d und e<strong>in</strong>ige weitere Methoden bereitgestellt werden,<br />
die den Umgang mit den Entitätsklassen erleichtern. Zum Abbilden<br />
von Beziehungen müssen die vom <strong>Framework</strong> bereitgestellten Behälterklassen<br />
verwendet werden. Für alle Datenkomponenten, die persistiert werden<br />
sollen, müssen Properties def<strong>in</strong>iert werden, die abstrakt und entweder geschützt<br />
oder öffentlich s<strong>in</strong>d. Properties, die dem Entwickler nur lesenden<br />
Zugriff ermöglichen oder die zusätzliche Programmlogik enthalten sollen,<br />
müssen doppelt implementiert werden. E<strong>in</strong>mal als abstrakt und geschützt,<br />
damit sie nur dem Persistierungsframework zugänglich s<strong>in</strong>d, und e<strong>in</strong> zweites<br />
Mal unter anderem Namen und öffentlich mit der gewünschten zusätzlichen<br />
Programmlogik, die den Zugriff auf die erste Property weiterleitet. <strong>Das</strong> Implementieren<br />
der Schnittstelle IDeleteCallback wird zusätzlich erforderlich,
3. Evaluierung 33<br />
wenn beim Löschen e<strong>in</strong>es Datensatzes die Detaildatensätze automatisch mitgelöscht<br />
werden sollen.<br />
NHibernate benötigt neben der ID-Property noch e<strong>in</strong>en parameterlosen<br />
Konstruktor <strong>in</strong> den Entitätsklassen. Behälterklassen für Beziehungen dürfen<br />
nur mit Schnittstellen, nicht jedoch mit konkreten Implementierungen<br />
def<strong>in</strong>iert werden. Soll Laden bei Bedarf zum E<strong>in</strong>satz kommen, müssen außerdem<br />
alle Methoden und Properties virtuell se<strong>in</strong>, damit NHibernate die<br />
<strong>in</strong> diesem Fall benötigten Proxies erzeugen kann. Datenkomponenten kann<br />
NHibernate entweder direkt oder über zugehörige Properties persistieren,<br />
auch wenn der Lese- oder Schreibzugriff privat oder geschützt ist.<br />
Beim <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> werden die Entitätsklassen normalerweise<br />
aus dem konzeptionellen Modell generiert. Die resultierenden Klassen<br />
s<strong>in</strong>d von System.Data.Objects.DataClasses.<strong>Entity</strong>Object abgeleitet, das<br />
selbst von StrukturalObject ableitet und die Schnittstellen I<strong>Entity</strong>WithKey,<br />
I<strong>Entity</strong>WithChangeTracker sowie I<strong>Entity</strong>WithRelationships implementiert.<br />
StrukturalObject implementiert die Schnittstellen INotifyPropertyChang<strong>in</strong>g<br />
sowie INotifyPropertyChanged. Da das <strong>Entity</strong> <strong>Framework</strong> und somit alle enthaltenen<br />
Klassen und Schnittstellen Teil des .<strong>NET</strong>-<strong>Framework</strong> s<strong>in</strong>d, wird<br />
dadurch ke<strong>in</strong>e Abhängigkeit zu zusätzlichen <strong>Framework</strong>s verursacht. Von<br />
der Idealvorstellung e<strong>in</strong>es POCO s<strong>in</strong>d diese Entitätsklassen trotzdem weit<br />
entfernt.<br />
Der generierte Quelltext wird bei jeder Änderung der Metadaten neu generiert.<br />
Die Entitätsklassen s<strong>in</strong>d deshalb als partielle Klassen def<strong>in</strong>iert und<br />
können somit manuell erweitert werden, ohne dass diese Änderungen von<br />
der automatischen Quelltextgenerierung überschrieben werden. Bei diesen<br />
manuellen Erweiterungen ist jedoch immer auf die vorhandene Programmlogik<br />
Rücksicht zu nehmen [19]. Die gebotenen Möglichkeiten s<strong>in</strong>d dadurch<br />
erheblich e<strong>in</strong>geschränkt. <strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> kann auch manuell erstellte<br />
Entitätsklassen persistieren. Bei solchen Klassen wird vorausgesetzt, dass<br />
sie die Schnittstellen I<strong>Entity</strong>WithKey, I<strong>Entity</strong>WithChangeTracker und I<strong>Entity</strong>WithRelationships<br />
implementieren, wenn zugehörige Funktionalität wie<br />
e<strong>in</strong> Id-Property, <strong>in</strong>tegrierte Änderungsüberwachung oder e<strong>in</strong>e Beziehung benötigt<br />
wird. Weitere Informationen dazu f<strong>in</strong>den sich <strong>in</strong> [22].<br />
Schon seit längerer Zeit stellen sich e<strong>in</strong>zelne Mitglieder des Entwicklungsteams<br />
der Diskussion mit Anwendern, die e<strong>in</strong>e weitere Annäherung an<br />
vollständige Unabhängigkeit der Entitätsklassen von der Persistenzschicht<br />
für die nächste Version des <strong>Entity</strong> <strong>Framework</strong> erwarten [49, 51].<br />
Wie schon <strong>in</strong> Unterabschnitt 3.2.3 ausgeführt wurde, unterstützt das<br />
<strong>Entity</strong> <strong>Framework</strong> nur bidirektionale Beziehungen, wodurch die eventuell<br />
gewünschte Kapselung aufgweicht wird, die die öffentliche Schnittstelle e<strong>in</strong>er<br />
Klasse unnötig erweitert wird.
3. Evaluierung 34<br />
3.3.2 Unterstützte Datenbanksysteme<br />
Beim <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> wird über e<strong>in</strong> Providermodell die Unterstützung<br />
unterschiedlicher RDBMS ermöglicht. Microsoft liefert nur Provider<br />
für die eigenen Datenbankprodukte. An der Unterstützung weiterer<br />
RDBMS wird von anderen Anbietern bereits gearbeitet [57]. Die Firma Devart<br />
bietet Provider für die Unterstützung von Oracle, MySQL, PostgreSQL<br />
und SQLite [7, 36, 38, 53, 54]. Unter [47, 63] wird e<strong>in</strong> SQLite-Provider zum<br />
Download angeboten. Provider für e<strong>in</strong>e Reihe weiterer RDBMS s<strong>in</strong>d angekündigt<br />
[57]. Sybase iAnywhere stellt mittlerweile auch e<strong>in</strong>en Provider für<br />
das <strong>Entity</strong> <strong>Framework</strong> zur Verfügung [48].<br />
Von den untersuchten Produkten unterstützt NHibernate zurzeit noch<br />
die größte Anzahl an Datenbanksystemen, wobei das <strong>Entity</strong> <strong>Framework</strong> bereits<br />
aufholt. Neben Microsoft SQL-Server, Oracle 9i und Oracle 10g, arbeitet<br />
NHibernate mit e<strong>in</strong>er Reihe weiterer kommerzieller und freier RDBMS<br />
zusammen [40].<br />
Genome unterstützt grundsätzlich nur den SQL-Server von Microsoft<br />
sowie dessen CE-Variante, Oracle 9i und 10g sowie IBM DB2, wobei diese<br />
Auswahl bei der Express-Edition weiter e<strong>in</strong>geschränkt ist.<br />
3.4 Produktivität<br />
3.4.1 Codegenerierung<br />
Enitätsklassen aus Metadaten generieren<br />
<strong>Das</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> generiert die Entitätsklassen automatisch<br />
entsprechend des konzeptionellen Schemas <strong>in</strong> den Metadaten. Änderungen<br />
direkt <strong>in</strong> den Metadaten oder über das grafische Designer-Werkzeug <strong>in</strong>itiieren<br />
beim Speichern die erneute Generierung der Quelltextes. Mit NHibernate<br />
wird seit der Version 1.2 das Kommandozeilenwerkzeug hbm2net mitgeliefert,<br />
das auch aus den Metadaten den Quelltext für die Entitätsklassen<br />
generieren kann. Genome wird ohne vergleichbare Funktionalität geliefert.<br />
Datenbank-Schema aus Metadaten generieren (Forward Eng<strong>in</strong>eer<strong>in</strong>g)<br />
Genome enthält e<strong>in</strong>en <strong>in</strong> Visual Studio <strong>in</strong>tegrierten Assistenten, der das Datenbankschema<br />
entsprechend den Metadaten aktualisiert. NHibernate bietet<br />
<strong>in</strong> der Laufzeitumgebung e<strong>in</strong>e entsprechende Funktionalität, die per Konfigurationse<strong>in</strong>stellung<br />
oder über e<strong>in</strong>en Aufruf der entsprechenden Funktion<br />
das Datenbankschema aus den Metadaten neu erzeugt. Beim <strong>ADO</strong>.<strong>NET</strong><br />
<strong>Entity</strong> <strong>Framework</strong> fehlt e<strong>in</strong>e enstprechende Funktionalität.
3. Evaluierung 35<br />
Abbildung 3.2: Assistent von Genome zum Erstellen der Metadaten aus<br />
e<strong>in</strong>er Entitätsklasse.<br />
Metadaten aus den Entitätsklassen generieren<br />
Genome kann aus dem Quelltext der Entitätsklassen die Metadaten erzeugen.<br />
Dazu wird im Kontextmenü des Quelltexteditors e<strong>in</strong> zusätzliches<br />
Untermenü „Genome <strong>Mapp<strong>in</strong>g</strong>“ e<strong>in</strong>geblendet, das e<strong>in</strong>e Reihe verschiedener<br />
Abbildungsmöglichkeiten zur Auswahl anbietet (siehe Abbildung 3.2).<br />
NHibernate kann die Metadaten zwar nicht aus dem Quelltext der Entitätsklassen<br />
generieren, bietet jedoch die Möglichkeit, die Metadaten als Attribute<br />
<strong>in</strong> den Quelltext zu <strong>in</strong>tegrieren. Die von NHibernate zur Laufzeit<br />
benötigten Metadaten im XML-Format kann es automatisch aus diesen generieren.<br />
<strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> bietet ke<strong>in</strong>e vergleichbare Funktionalität.<br />
Entitätsklassen und Metdaten aus dem Datenbankschema generieren<br />
(Reverse Eng<strong>in</strong>eer<strong>in</strong>g)<br />
<strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> sowie Genome bieten <strong>in</strong> Visual Studio <strong>in</strong>tegrierte<br />
Assistenten, die aus e<strong>in</strong>er Datenbank, die über die Verb<strong>in</strong>dungsparameter<br />
festgelegt wird, die Metadaten und die Entitätsklassen automatisch gene-
3. Evaluierung 36<br />
rieren. Dabei wird davon ausgegangen, dass das konzeptionelle Modell dem<br />
Datenbankschema direkt entspricht. Bei den Assistenten beider Produkte<br />
können Tabellen und Views ausgewählt werden, welche verarbeitet werden<br />
sollen. Beziehungen <strong>in</strong> der Datenbank werden generell als normale Beziehung<br />
importiert, auch wenn diese als Vererbung gedacht waren. Die richtige<br />
Beziehungsvariante automatisch zu erkennen ist kaum möglich, da sich<br />
die Varianten im Datenbankschema nicht e<strong>in</strong>deutig unterscheiden lassen.<br />
Die falsch erzeugten Beziehungen zwischen Entitätsklassen und die entsprechenden<br />
Metadaten müssen nachträglich manuell korrigiert werden. Wünschenswert<br />
wäre es daher, über e<strong>in</strong>en Dialog die richtige Variante vor dem<br />
Generieren auswählen zu können.<br />
Beide Produkte können, neben der <strong>in</strong>itialen Erzeugung der Metadaten<br />
und der Entitätsklassen, auch nachträgliche Änderungen übernehmen. <strong>Das</strong><br />
<strong>Entity</strong> <strong>Framework</strong> sollte dabei das Speichermodell aktualisieren, sowie neu<br />
h<strong>in</strong>zugekommene Elemente dem konzeptionellen Schema und der Abbildungsdef<strong>in</strong>ition<br />
h<strong>in</strong>zufügen, aber manuelle Anpassungen im konzeptionellen<br />
Modell unberührt lassen. Leider funktioniert das nicht zuverlässig [4, 10].<br />
So müssen teilweise Änderungen im konzeptionellen Modell, nach jeder Aktualisierung<br />
aus dem Datenbankmodell, wieder manuell berichtigt werden.<br />
Während dieser Arbeit wurde diese Vorgehensweise <strong>in</strong> Genome nicht näher<br />
untersucht, da es durchwegs e<strong>in</strong>facher erschien, alle Änderungen <strong>in</strong> den Entitätsklassen<br />
manuell durchzuführen und daraus über den Assistenten die<br />
Metadaten aktualisieren zu lassen.<br />
NHibernate wird ohne vergleichbare Funktionalität geliefert. Wie bei<br />
Genome s<strong>in</strong>d der Quellcode der Entitätsklassen und die Metadaten so übersichtlich,<br />
dass sie für e<strong>in</strong> Projekt <strong>in</strong> der Größenordnung der Beispielapplikation<br />
und auch darüber h<strong>in</strong>aus, ohne weiteres manuell erstellt und gewartet<br />
werden können. Es s<strong>in</strong>d jedoch von Drittanbietern entsprechende Werkzeuge<br />
verfügbar [39, 42].<br />
3.4.2 Designer-Werkzeug<br />
Wie bei Microsoft-Produkten üblich, wird auch das <strong>Entity</strong> <strong>Framework</strong> mit<br />
e<strong>in</strong>em grafischen Designer-Werkzeug geliefert, das den Entwickler <strong>in</strong> diesem<br />
Fall von der mühsamen und komplizierten manuellen Bearbeitung der XML-<br />
Metadaten befreien soll. Abbildung 3.3 zeigt e<strong>in</strong>ige grundlegende Elemente<br />
des grafischen Designer-Werkzeugs. Der l<strong>in</strong>ke obere Bereich <strong>in</strong> dieser Abbildung<br />
zeigt den Entwurfsbereich für das konzeptionelle Modell. Damit können<br />
neue Entitätsklassen e<strong>in</strong>gefügt werden, bestehende geändert oder gelöscht<br />
werden. Weiters können Beziehungen zwischen den Klassen erstellt und bearbeitet<br />
werden. Der „Model Browser“, nimmt <strong>in</strong> der Abbildung den rechten<br />
oberen Bereich e<strong>in</strong>. Damit kann im gesamten <strong>Entity</strong> Data Model navigiert<br />
werden. Die Abbildungsdef<strong>in</strong>ition kann über das „<strong>Mapp<strong>in</strong>g</strong> Details“-Fenster<br />
bearbeitet werden, das <strong>in</strong> der Abbildung l<strong>in</strong>ks unten gezeigt wird. Über das
3. Evaluierung 37<br />
Abbildung 3.3: Grafisches Designer-Werkzeug des Microsoft <strong>ADO</strong>.<strong>NET</strong><br />
<strong>Entity</strong> <strong>Framework</strong>.<br />
im rechten unteren Bereich dargestellten Eigenschaftsfenster können weitere<br />
Eigenschaften des jeweils <strong>in</strong> e<strong>in</strong>em der anderen Bereiche ausgewählten<br />
Elements, angezeigt und teilweise bearbeitet werden.<br />
Zurzeit bietet das Designer-Werkzeug für wesentliche Konstrukte noch
3. Evaluierung 38<br />
ke<strong>in</strong>e Unterstützung, wie z. B. Vererbung mit e<strong>in</strong>er Klasse pro Tabelle, Vererbung<br />
mit e<strong>in</strong>er Klasse pro konkreter Tabelle oder e<strong>in</strong>gebetteter Wert.<br />
Die manuelle Bearbeitung der Metadaten ist daher oft unerlässlich. Werden<br />
Elemente wie z. B. ComplexType für e<strong>in</strong>gebettete Werte, die das Designer-<br />
Werkzeug nicht unterstützt, manuell e<strong>in</strong>gefügt, lässt sich diese Datei nicht<br />
mehr mit dem Designer-Werkzeug öffnen. Weiters ist nicht vorgesehen, das<br />
Speichermodell im Designer-Werkzeug zu bearbeiten, es kann aber über<br />
„Update Model from Database“ aus e<strong>in</strong>em vorhandenen Datenbankschema<br />
generiert werden. Dabei werden auch das konzeptionelle Modell und die<br />
Abbildungsdef<strong>in</strong>ition generiert, bzw. bei Vorhandense<strong>in</strong> aktualisiert, wobei<br />
manuell vorgenommene Änderungen teilweise überschrieben oder verworfen<br />
werden.<br />
NHibernate und Genome werden ohne grafisches Designer-Werkzeug geliefert.<br />
3.4.3 Visual Studio Integration<br />
Alle Assistenten und das grafische Designer-Werkzeug des <strong>Entity</strong> <strong>Framework</strong><br />
s<strong>in</strong>d Teil von Visual Studio Service Pack 1 und s<strong>in</strong>d entsprechend vollständig<br />
<strong>in</strong>tegriert. Genome liefert zwar ke<strong>in</strong>en grafisches Designer-Werkzeug,<br />
aber e<strong>in</strong>e Reihe von Assistenten, die durchwegs <strong>in</strong>nerhalb von Visual Studio<br />
über Kontextmenüs an den relevanten Stellen aufgerufen werden können<br />
sowie Visual Studio-Projektvorlagen für verschiedene Anwendungsfälle. Die<br />
von NHibernate gebotene Visual Studio-Integration fällt dagegen etwas m<strong>in</strong>imalistisch<br />
aus. Mitgelieferte XML-Schema-Dateien aktivieren Intellisense<br />
beim Bearbeiten der XML-Metadatendateien. Diese Dateien s<strong>in</strong>d manuell <strong>in</strong><br />
das Visual Studio-Installationsverzeichnis zu kopieren [KBK08, S. 40] [12].
Kapitel 4<br />
Implementierung<br />
Der Quelltext der Beispielanwendung bef<strong>in</strong>det sich auf der beiliegenden CD<br />
im Anhang.<br />
4.1 Anforderungen<br />
Die erstellte Beispielapplikation soll wesentliche Elemente be<strong>in</strong>halten, die <strong>in</strong><br />
typischen Geschäftsapplikationen Verwendung f<strong>in</strong>den, deren Daten <strong>in</strong> relationalen<br />
Datenbanksystemen persistiert werden. Dazu zählen jedenfalls 1:n-<br />
Beziehungen wie sie <strong>in</strong> relationalen Datenbanksystemen üblich s<strong>in</strong>d. Weiters<br />
soll gezeigt werden, welche der beim objektorientierten Entwurf üblichen<br />
Konstrukte mit Standardprodukten <strong>in</strong> RDBMS persistierbar s<strong>in</strong>d.<br />
Dazu zählt zum<strong>in</strong>dest die Vererbung sowie m:n-Beziehungen. Objektmodelle<br />
s<strong>in</strong>d üblicherweise fe<strong>in</strong>granularer als relationale Modelle (siehe Unterabschnitt<br />
2.2.3). Ob diese trotzdem persistiert werden können, ist e<strong>in</strong> weiterer<br />
untersuchter Punkt. Die Idealvorstellung ist, dass die Persistierung der Objekte<br />
<strong>in</strong> e<strong>in</strong> RDBMS transparent passieren soll und dem Entwickler beim<br />
objektorientierten Entwurf ke<strong>in</strong>e E<strong>in</strong>schränkungen auferlegt werden sollen,<br />
nur um diese Persistierung zu ermöglichen (siehe Unterabschnitt 2.2.8). Entsprechend<br />
unkompliziert soll auch das Wiederherstellen persistierter Objekte<br />
ablaufen (siehe Unterabschnitt 2.2.7).<br />
Der Schwerpunkt der Beispielanwendung liegt jedenfalls beim objektorientierten<br />
Entwurf. <strong>Das</strong> Abbilden gewachsener Datenbankschemata auf<br />
Objekte bleibt unberücksichtigt. Deshalb wurden beispielsweise nur künstliche<br />
Schlüssel verwendet. Die Unterstützung natürlicher Schlüssel oder gar<br />
zusammengesetzter natürlichen Schlüssel durch das Persistenz-<strong>Framework</strong><br />
wurden dagegen nicht untersucht. Die Beispielapplikation soll möglichst<br />
ohne Änderungen mit allen unterstützten Datenbanken funktionieren. Dieser<br />
Aspekt wurde zwar nicht konkret untersucht, soweit möglich wurde jedoch<br />
darauf verzichtet, Funktionalität zu verwenden, die nur von e<strong>in</strong>zelnen<br />
RDBMS geboten wird, wie z. B. der Identity-Datentyp des Microsoft SQL-<br />
39
4. Implementierung 40<br />
Server.<br />
Mit jedem Produkte soll gezeigt werden, wie weit diese Anforderungen<br />
erfüllt werden können bzw. wo Abstriche notwendig s<strong>in</strong>d. Es war vorgesehen,<br />
e<strong>in</strong> e<strong>in</strong>heitliches Datenbankschema für alle drei Implementierungen zu<br />
verwenden. Für Genome musste jedoch von diesem geme<strong>in</strong>samen Datenbankschema<br />
abgewichen werden (siehe Unterabschnitt 3.2.5 und Unterabschnitt<br />
3.2.6).<br />
4.2 Realisierung<br />
Mit allen drei Produkten wurde e<strong>in</strong>e Clientapplikation entwickelt, die alle<br />
Datensätze löscht und die Tabellen neu mit Daten befüllt. Weiters kam<br />
auch das Wiederherstellen der Objekte aus den Datensätzen der Datenbank<br />
zum E<strong>in</strong>satz. Getestet wurde die Applikation mit dem Microsoft SQL-Server<br />
2005 Express Edition. Abbildung 4.1 zeigt das Klassendiagramm der Beispielanwendung<br />
und Abbildung 4.2 das entsprechende Datenbankschema, <strong>in</strong><br />
das die Objekte persistiert werden.<br />
4.2.1 Visual Studio Projektorganisation<br />
Die verschiedenen Projekte für die drei Implementierungen, wurden zu e<strong>in</strong>er<br />
geme<strong>in</strong>samen Visual Studio-Solution zusammengefasst. Für NHibernate<br />
wurden die Entitätsklassen im Projekt DAL_NHibernate, die Metadaten<br />
im Unterordner HBM erstellt. Im Projekt Client_NHibernate bef<strong>in</strong>det sich<br />
die Clientapplikation. <strong>Das</strong> <strong>Entity</strong> Data Model des <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
bef<strong>in</strong>det sich im Projekt DAL_EF. Die manuell erstellten Erweiterungen<br />
zu den generierten Entitätsklassen im Unterordner ERPEntities.<br />
Für die zugehörige Clientapplikation wurde das Projekt Client_EF erstellt.<br />
Die Aufteilung für Genome weicht etwas von den anderen beiden Lösungen<br />
ab. Genome verlangt e<strong>in</strong> eigenes Projekt für die Metadaten, dafür wurden<br />
der Projektname DAL_Genome verwendet. Die Entitätsklassen bef<strong>in</strong>den<br />
sich <strong>in</strong> Bus<strong>in</strong>ess_Genome, die Clientapplikation wieder erwartungsgemäß<br />
<strong>in</strong> Client_Genome. Um e<strong>in</strong>e bestimmte Lösung aus Visual Studio heraus<br />
auszuführen, ist es notwendig vorher die entsprechende Clientapplikation<br />
als Startprojekt festzulegen.<br />
4.2.2 Vererbung<br />
Alle drei <strong>in</strong> Unterabschnitt 2.2.4 beschriebenen Varianten der Vererbung,<br />
wurden <strong>in</strong> der Beispielapplikation umgesetzt. Die Klasse Contacts und die<br />
davon abgeleiteten Klassen Customer und Vendor, werden mit Vererbung<br />
mit e<strong>in</strong>er Tabelle pro Klasse auf die entsprechenden Tabellen Contact, Customer<br />
und Vendor abgebildet. Die Klassen SalesOrder und PurchOrder mit
4. Implementierung 41<br />
Abbildung 4.1: <strong>Das</strong> Klassendiagramm der NHibernate-Implementierung.<br />
der Basisklasse Order, sowie die Klassen SalesOrderL<strong>in</strong>e und PurchOrderL<strong>in</strong>e<br />
mit der Basisklasse OrderL<strong>in</strong>e, werden mit Vererbung mit e<strong>in</strong>er Tabelle<br />
pro konkreter Klasse auf die Tabellen SalesOrder, SalesOrderL<strong>in</strong>e, PurchOrder<br />
und PurchOrderL<strong>in</strong>e abgebildet. Die dritte Variante, Vererbungshierarchie<br />
<strong>in</strong> e<strong>in</strong>er Tabelle, kommt bei den Klassen Article und Service mit der<br />
geme<strong>in</strong>samen Basisklasse Item zum E<strong>in</strong>satz. Im Genome-spezifischen Datenbankschema<br />
wurde <strong>in</strong> der Tabelle Contact zusätzlich das von Genome<br />
benötigte Diskrim<strong>in</strong>ator-Attribut ContactType e<strong>in</strong>gefügt.
4. Implementierung 42<br />
Country<br />
Id<br />
ISOCode<br />
Name<br />
Version<br />
AlternativeAddress<br />
Id<br />
StreetAddress<br />
City<br />
ZipCode<br />
CountryId<br />
ContactId<br />
Version<br />
SalesOrderL<strong>in</strong>e<br />
Id<br />
SalesOrderId<br />
ItemCount<br />
ItemPrice<br />
TaxCode<br />
ItemId<br />
Version<br />
RowId<br />
Id<br />
NextValue<br />
Version<br />
Customer<br />
Id<br />
SalesOrder<br />
Id<br />
PaymentDueDate<br />
CustomerId<br />
Version<br />
OrderDate<br />
Contact<br />
Id<br />
FirstName<br />
LastName<br />
StreetAddress<br />
City<br />
ZipCode<br />
CountryId<br />
Version<br />
Item<br />
Id<br />
ItemNumber<br />
ItemName<br />
Price<br />
StockCount<br />
ItemType<br />
Version<br />
Vendor<br />
Id<br />
PurchOrder<br />
Id<br />
VendorId<br />
Version<br />
OrderDate<br />
DiscountPercent<br />
PurchOrderL<strong>in</strong>e<br />
Id<br />
VendorItem<br />
PurchOrderId<br />
ItemCount<br />
ItemPrice<br />
TaxCode<br />
ItemId<br />
Version<br />
VendorId<br />
Abbildung 4.2: <strong>Das</strong> Datenbankschema der <strong>Entity</strong> <strong>Framework</strong>- und<br />
NHibernate-Implementierung.<br />
4.2.3 ID-Generierung<br />
Alle Produkte im Vergleich untertützen verschiedene Möglichkeiten, Werte<br />
für die künstlichen Schlüssel zu generieren und zuzuweisen. Die für die Beispielapplikation<br />
gewählte Variante sollte vor allem mit jedem RDBMS ohne<br />
weitere Anpassung funktionieren und trotzdem effizient se<strong>in</strong>. Am effizientesten<br />
ist der Sequence-Mechanismus (siehe Unterabschnitt 2.2.1). Leider wird<br />
dieser nicht von allen RDBMS unterstützt. Aus diesem Grund wurde die<br />
Variante gewählt, die den Sequence-Mechanismus nachbildet. Dafür wurde<br />
ItemId
4. Implementierung 43<br />
e<strong>in</strong>e zusätzliche Tabelle RowId wurde e<strong>in</strong>geführt mit e<strong>in</strong>em Attribut Next-<br />
Value, <strong>in</strong> dem der nächste verfügbare Wert abgelegt wird. Die Attribute Id<br />
und Version s<strong>in</strong>d für die Verwendung durch das O/R-<strong>Mapp<strong>in</strong>g</strong>-Framwork<br />
notwendig.<br />
NHibernate unterstützt diese Variante direkt. Es genügte somit die Metadaten<br />
entsprechend zu ergänzen. <strong>Das</strong> <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> und<br />
Genome h<strong>in</strong>gegen bieten ke<strong>in</strong>e entsprechende Unterstützung. Es war deshalb<br />
notwendig, e<strong>in</strong>e eigene Lösung für das Abholen neuer Werte, sowie das<br />
Zuweisen an neu erzeugte Objekte zu implementieren.<br />
Der Zugriff auf die Tabelle RowId wurde, wie auch bei den anderen Tabellen<br />
an das jeweilige O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> delegiert. Jedoch musste<br />
dazu e<strong>in</strong>e eigene Arbeitse<strong>in</strong>heit erzeugt werden, da dieser Zugriff nicht <strong>in</strong><br />
der selben Transaktion durchgeführt werden darf wie die restlichen Datenbankzugriffe.<br />
In der zugehörigen Enitätsklasse wurde e<strong>in</strong>e Klassenmethode<br />
NextId implementiert, die e<strong>in</strong>e gewisse Anzahl an IDs <strong>in</strong> der Tabelle reserviert<br />
und diese reservierten Werte nach und nach an Aufrufer der Methode<br />
abgibt, bis diese aufgebraucht s<strong>in</strong>d um dann wieder mehrere Werte auf e<strong>in</strong><br />
Mal zu reservieren. Damit gleichzeitige Versuche mehrere Clients, neue IDs<br />
zu reservieren wird durch optimistische verb<strong>in</strong>dungslose Sperre erkannt. Im<br />
Kollisionsfall wird die Reservierung wiederholt. Stored Procedures oder angepasste<br />
SQL-Befehle, die das Attribut NextValue erhöhen wären für diesen<br />
Zweck effizienter. Der Zweck dieser Lösung war jedoch, die grundsätzliche<br />
Machbarkeit zu prüfen ohne den Anspruch auf die effizienteste Implementierung<br />
zu stellen. E<strong>in</strong>e weitere Herausforderung war das Zuweisen der ID-<br />
Werte an neue Entitäten. Der Konstruktor eignet sich dazu nicht, da dieser<br />
auch aufgerufen wird, wenn e<strong>in</strong> Objekt aus der Datenbank wiederhergestellt<br />
wird.<br />
Beim <strong>Entity</strong> <strong>Framework</strong> schien das Ereignis Sav<strong>in</strong>gChanges der Arbeitse<strong>in</strong>heit<br />
(ObjectContext) der beste Zeitpunkt für die Zuweisung der neuen<br />
ID-Werte zu se<strong>in</strong>. Zu diesem Zeitpunkt können die betreffenden Objekte<br />
bereits unterschieden werden und es ist noch rechtzeitig vor dem Schreiben<br />
der Werte <strong>in</strong> die Datenbank. Die Arbeitse<strong>in</strong>heit bietet Zugriff auf den ObjectStateManager,<br />
über den alle <strong>in</strong> dieser Arbeitse<strong>in</strong>heit neu h<strong>in</strong>zugefügten<br />
Entitäten abgefragt werden können. Die Entitätsklassen müssen die Schnittstelle<br />
I<strong>Entity</strong> und somit die Methode SetId implementieren, über die die<br />
Werte zugewiesen werden.<br />
Für Genome wurde das Anfordern neuer ID-Werte auf die gleiche Weise<br />
realisiert, wie für das <strong>Entity</strong> <strong>Framework</strong>. <strong>Das</strong> Zuweisen der Werte ließ sich<br />
dagegen wesentlich e<strong>in</strong>facher realisieren. E<strong>in</strong> von e<strong>in</strong>er Fabrikmethode des<br />
<strong>Framework</strong>s benötigter Konstruktor wird nur dann aufgerufen, wenn neue<br />
Objekte erzeugt werden. Daher kann zu diesem Zeitpunkt e<strong>in</strong> neuer ID-Wert<br />
e<strong>in</strong>fach zugewiesen werden. Es ist jedoch notwendig, diese Zuweisung <strong>in</strong> jede<br />
Entitätsklasse zu e<strong>in</strong>zubauen.
4. Implementierung 44<br />
4.2.4 Beziehungen<br />
Es wurden e<strong>in</strong>ige 1:n-Beziehungen def<strong>in</strong>iert, wie z. B. zwischen Contact und<br />
AlternativeAddress oder zwischen PurchOrder und Vendor bzw. SalesOrder<br />
und Customer. Wobei im ersten Fall die l<strong>in</strong>ke Seite der Beziehung e<strong>in</strong>e<br />
abstrakte Basisklasse ist, die diese Beziehung an die abgeleiteten Entitäten<br />
vererbt, bei den letzten Beiden Fällen wurde die Beziehung <strong>in</strong> den abgeleiteten<br />
Klassen def<strong>in</strong>iert. Bei der Beziehungen zwischen OrderL<strong>in</strong>e und<br />
Item, werden beide Seiten der Beziehung von den abstrakten Basisklassen,<br />
an die abgeleiteten Klassen vererbt. Die Klasse Address sollte als e<strong>in</strong>gebetteter<br />
Wert abgebildet werden und die 1:n-Beziehung zu Country sollte<br />
deshalb e<strong>in</strong>e Beziehung von e<strong>in</strong>em e<strong>in</strong>gebetteten Wert zu e<strong>in</strong>er weiteren Entität<br />
darstellen. Da das <strong>Entity</strong> <strong>Framework</strong> und Genome solche Beziehungen<br />
nicht unterstützen, wurde diese Variante nur mit NHibernate realisiert (siehe<br />
Unterabschnitt 4.2.5). E<strong>in</strong>e n:m-Beziehung wurde zwischen den Entitäten<br />
Vendor und Article realisiert, die widergeben soll, welche Artikel von welchem<br />
Lieferanten bestellt werden können.<br />
4.2.5 Fe<strong>in</strong>granulares Objektmodell<br />
Die Klasse Address sollte als e<strong>in</strong> Attribut der Entitäten Contact sowie AlternativeAddress<br />
realisiert werden, wie im Unterabschnitt 2.2.3 als e<strong>in</strong>gebetter<br />
Wert beschrieben. <strong>Das</strong> <strong>Entity</strong> <strong>Framework</strong> und Genome können Beziehung<br />
zwischen e<strong>in</strong>gebetten Objekten und weiteren Entitäten nicht abbilden, deshalb<br />
wurden die Addressattribute direkt <strong>in</strong> die Entitäten Contact sowie AlternativeAddress<br />
e<strong>in</strong>gefügt. Nur mit NHibernate konnte diese Konstruktion<br />
wie vorgesehen umgesetzt werden.<br />
4.2.6 Nebenläufigkeit<br />
Zur Erkennung von Konflikten bei gleichzeitigen Änderungen durch mehrere<br />
Geschäftstransaktionen wurde optimistische verb<strong>in</strong>dungslose Sperre mit<br />
e<strong>in</strong>em eigens dafür erstelltem Attribut „Version“ vom Datentyp Ganzzahl<br />
verwendet. Genome unterstützt mit dem Microsoft SQL-Server für diesen<br />
Zweck nur den Datentyp Timestamp. <strong>Das</strong> war e<strong>in</strong>er der <strong>in</strong> Abschnitt 4.1 angeführten<br />
Gründe, warum für Genome e<strong>in</strong> abweichendes Datenbankschema<br />
erstellt wurde.<br />
Auch das <strong>Entity</strong> <strong>Framework</strong> bietet für e<strong>in</strong> Versionsfeld vom Datentyp<br />
Ganzzahl nur unvollständige Unterstützung. E<strong>in</strong> entsprechendes Attribut<br />
vom Datentyp Timestamp, wird vom Microsoft SQL-Server bei jeder Änderung<br />
des Datensatzes automatisch aktualisiert. Bei Ganzzahl muss diese<br />
Aktualisierung vom O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong> selbst vorgenommen werden.<br />
Im <strong>Entity</strong> <strong>Framework</strong> ist das jedoch nicht vorgesehen, weshalb dafür weitere<br />
Anpassungen notwendig s<strong>in</strong>d. Wie beim Zuweisen neuer ID-Werte, war<br />
das Ereignis Sav<strong>in</strong>gChanges der Arbeitse<strong>in</strong>heit auch hier zielführend. Der
4. Implementierung 45<br />
ObjectStateManager liefert alle Enitäten, die <strong>in</strong> der aktuellen Arbeitse<strong>in</strong>heit<br />
geändert wurden. Die bereits erstellte Schnittstelle I<strong>Entity</strong> wurde um die<br />
Methode SetModified erweitert, die das Versionsattribut <strong>in</strong>krementiert.
Kapitel 5<br />
Resumee und Ausblick<br />
5.1 Resumee<br />
NHibernate<br />
NHibernate macht e<strong>in</strong>en soliden und ausgereiften E<strong>in</strong>druck. Grafische Werkzeuge<br />
zum Bearbeiten der Metadaten wären wünschenswert, aber auch nur<br />
mit e<strong>in</strong>em XML-Editor ausgestattet geht die Arbeit leicht von der Hand.<br />
Außer den Angaben, welche Klassen und Properties persistiert werden sollen,<br />
s<strong>in</strong>d nur von Vorgabewerten abweichende Angaben zu erfassen. NHibernate<br />
bietet e<strong>in</strong>e umfangreiche Unterstützung für alle grundlegenden und<br />
viele weitere Abbildungsszenarien. E<strong>in</strong>e großer Vorteil von NHibernate ist<br />
die kurze und prägnante Darstellung der Metadaten für die Abbildung. Die<br />
meisten Konstrukte werden explizit mit entsprechenden XML-Elementen<br />
ausgedrückt (siehe z. B. Unterabschnitt 3.2.5), wodurch die Metadaten für<br />
den Entwickler leichter zu <strong>in</strong>terpretieren und entsprechend e<strong>in</strong>fach zu warten<br />
s<strong>in</strong>d. Beim Entwurf der Entitätsklassen s<strong>in</strong>d nur wenige Kompromisse<br />
e<strong>in</strong>zugehen, um die Anforderungen an das <strong>Framework</strong> zu erfüllen.<br />
E<strong>in</strong> wesentliches Manko, dessen Behebung auch von den Entwicklern<br />
hohe Priorität beigemessen wird, ist die fehlende LINQ-Unterstützung, die<br />
bereits <strong>in</strong> Arbeit ist und mit der nächsten Version 2.1 erwartet wird.<br />
Genome<br />
Genome ist e<strong>in</strong> etabliertes Produkt e<strong>in</strong>es kommerziellen Anbieters. E<strong>in</strong>faches<br />
und effizientes Arbeiten wird durch die vorbildliche Integration <strong>in</strong> Visual<br />
Studio ermöglicht. LINQ wird schon seit längerer Zeit unterstützt, was<br />
untermauert, dass Genome aktiv weiterentwickelt wird. Die Metadaten s<strong>in</strong>d<br />
noch etwas übersichtlicher als bei NHibernate, was zum Teil auch daran liegt,<br />
dass etwas weniger Abbildungsszenarien unterstützt werden. Die Auswahl<br />
an unterstützten RDBMS lässt erkennen, dass der Fokus bei kommerziellen<br />
Applikationen liegt.<br />
46
5. Resumee und Ausblick 47<br />
Die Vorgaben beim Entwurf von Entitätsklassen gehen wesentlich weiter<br />
als bei NHibernate. Zu bemängeln ist vor allem die fehlende Unterstützung<br />
von Beziehungen <strong>in</strong> e<strong>in</strong>gebetteten Objekten.<br />
<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong><br />
Wie von Microsoft gewohnt und von den Anwendern erwartet, liegt beim<br />
<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> e<strong>in</strong> Schwerpunkt bei der e<strong>in</strong>fachen und <strong>in</strong>tuitiven<br />
Bedienung per grafischen Designer-Werkzeug und Assistenten.<br />
Leider können mit dem grafischen Designer-Werkzeug e<strong>in</strong>ige grundlegende<br />
Arbeitsschritte nicht erledigen werden. Für Applikationen, bei denen der<br />
Objektentwurf das Datenbankmodell vorgibt, fehlt das Generieren des Datenbankschemas<br />
aus den Metadaten (Forward eng<strong>in</strong>eer<strong>in</strong>g). Der umgekehrte<br />
Weg, das Erstellen des konzeptionellen Modells aus dem Datenbankschema<br />
(Reverse Eng<strong>in</strong>eer<strong>in</strong>g), kann nur beim Projektstart s<strong>in</strong>nvoll e<strong>in</strong>gesetzt<br />
werden, da manuell durchgeführte Anpassungen im konzeptionellen Modell,<br />
dadurch überschrieben werden. Es würde genügen, diesen Vorgang so e<strong>in</strong>zuschränken,<br />
dass damit ausschließlich das Speichermodell aktualisiert wird,<br />
denn damit wäre das Arbeiten mit dem grafischen Designer-Werkzeug halbwegs<br />
praktikabel. Um das <strong>Entity</strong> Data Model manuell zu bearbeiten, ist es<br />
zu komplex. Schon <strong>in</strong> den Metadaten der erstellten Beispielapplikation fällt<br />
es schwer, sich zurechtzuf<strong>in</strong>den, obwohl diese Anwendung sehr m<strong>in</strong>imalistisch<br />
ausgeführt ist.<br />
Die Laufzeitumgebung funktioniert und die grundlegenden Abbildungsszenarien<br />
s<strong>in</strong>d realisierbar, für e<strong>in</strong>fache Demonstrationen reicht es allemal.<br />
Beim Designer-Werkzeug kann man erkennen, wie sich Microsoft den Entwurf<br />
der Datenbankzugriffsschicht vorstellt. Für Microsoft ist es e<strong>in</strong> guter<br />
Zeitpunkt, das Produkt öffentlich zugänglich zu machen, um Rückmeldungen<br />
zu erhalten, wie weit die Vorstellungen der <strong>in</strong>teressierten Entwickler<br />
getroffen wurden.<br />
Wenngleich das <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> noch weit vom Reifegrad<br />
von Genome oder NHibernate entfernt ist, sollte es bereits e<strong>in</strong>e Verbesserung<br />
gegenüber den bisher verfügbaren .<strong>NET</strong>-Möglichkeiten, wie z. B. Datasets,<br />
darstellen. Vor allem die LINQ-Unterstützung trägt e<strong>in</strong>en wesentlichen Teil<br />
dazu bei. Bei komplexeren Projekten s<strong>in</strong>d Genome und NHibernate zurzeit<br />
e<strong>in</strong>deutig die bessere Wahl.<br />
5.2 Ausblick<br />
Wie schon der Abschnitt Grundlagen zeigt, ist das Themengebiet Objektpersistierung<br />
vielschichtig und komplex. E<strong>in</strong>ige zusätzliche Aspekte müssten untersucht<br />
werden, um weitere wichtigen Informationen für e<strong>in</strong>e entsprechende<br />
Entscheidung zu erhalten. Dazu zählen vor allem das Verhalten unter großer
5. Resumee und Ausblick 48<br />
Last mit vielen Datensätzen sowie verteilte Systeme. Viele Aspekte würden<br />
trotzdem erst bei der Umsetzung konkreter Projekte zu Tage treten.<br />
Nach der langen Entwicklungszeit bis zur ersten fertigen Version, sollte<br />
man von Microsoft e<strong>in</strong> leistungsfähigeres Produkt, als es das <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong><br />
<strong>Framework</strong> zurzeit ist, erwarten können. Die nächsten Versionen werden<br />
zeigen, ob die Komplexität des <strong>Entity</strong> Data Model gerechtfertigt ist und neue<br />
Möglichkeiten eröffnet oder ob damit e<strong>in</strong>fach über das Ziel h<strong>in</strong>ausgeschossen<br />
wurde. Für Projekte mit e<strong>in</strong>er großen Anzahl von Entitäten ist nach<br />
Me<strong>in</strong>ung des Autors, e<strong>in</strong> grafisches Designer-Werkzeug, wie der des <strong>Entity</strong><br />
<strong>Framework</strong>, wenig geeignet. Dazu müsste zum<strong>in</strong>dest die Möglichkeit geboten<br />
werden, mehrere Ausschnitte des konzeptionellen Modells zu erstellen,<br />
um diese unabhängig bearbeiten zu können. Auch wenn die Laufzeitumgebung<br />
des <strong>Entity</strong> <strong>Framework</strong> die relevanten Abbildungsszenarien bereits unterstützt,<br />
muss sich <strong>in</strong> der Praxis erst zeigen, ob das Produkt bei steigenden<br />
Last die notwendige Leistung erbr<strong>in</strong>gt.<br />
NHibernate ist e<strong>in</strong> leistungsfähiges O/R-<strong>Mapp<strong>in</strong>g</strong>-<strong>Framework</strong>. Sobald<br />
die LINQ-Unterstützung zur Verfügung steht, bleiben bei NHibernate kaum<br />
mehr Wünsche offen. Für quelloffene Projekte wird es daher auf längere<br />
Zeit e<strong>in</strong>e gute Wahl bleiben. M<strong>in</strong>destens so lange, bis auch freie Entwicklungsumgebungen<br />
e<strong>in</strong> grafisches Design-Werkzeug für das <strong>Entity</strong> <strong>Framework</strong><br />
bieten.<br />
Wer e<strong>in</strong> kommerzielles Produkt bevorzugt, ist zur Zeit mit Genome wesentlich<br />
besser bedient als mit dem <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>.<br />
Zum<strong>in</strong>dest hat Microsoft endlich e<strong>in</strong> Produkt auf dem Markt platziert,<br />
muss sich aber an anderen Lösungen messen lassen, die für .<strong>NET</strong> sowie für<br />
Java verfügbar s<strong>in</strong>d.
Literaturverzeichnis<br />
[Amb06a] Ambler, Scott W.: <strong>Mapp<strong>in</strong>g</strong> Objects to Relational Databases:<br />
O/R <strong>Mapp<strong>in</strong>g</strong> In Detail. http://www.agiledata.org/essays/<br />
mapp<strong>in</strong>gObjects.html. Version: Oktober 2006. – Letzter Zugriff:<br />
2008-01-16 18:34<br />
[Amb06b] Ambler, Scott W.: The Object-Relational Impedance Mismatch.<br />
http://www.agiledata.org/essays/impedanceMismatch.<br />
html. Version: Februar 2006. – Letzter Zugriff: 2008-01-16 18:38<br />
[Bau06] Bauer, Christian: Java Persistence with Hibernate. Revised.<br />
Mann<strong>in</strong>g, 2006. – 904 S. – ISBN 1932394885<br />
[Cod90] Codd, Edgar F.: The Relational Model for Database Management<br />
Version 2. Addison-Wesley Longman, Amsterdam, 1990. –<br />
538 S. – ISBN 0201141922<br />
[Dij82] Dijkstra, Edsger W.: Selected Writ<strong>in</strong>gs on Comput<strong>in</strong>g: A Personal<br />
Perspective. Spr<strong>in</strong>ger-Verlag, 1982. – 362 S. – ISBN<br />
0387906525<br />
[Esp04] Esposito, D<strong>in</strong>o: A First Look at ObjectSpaces <strong>in</strong> Visual Studio<br />
"Whidbey". http://msdn2.microsoft.com/en-us/library/ms971512.<br />
aspx. Version: Februar 2004. – Letzter Zugriff: 2008-01-19 10:49<br />
[Eva03] Evans, Eric: Doma<strong>in</strong>-Driven Design: Tackl<strong>in</strong>g Complexity <strong>in</strong> the<br />
Heart of Software. 1. A. Addison-Wesley Longman, Amsterdam,<br />
2003. – 560 S. – ISBN 0321125215<br />
[FRF02] Fowler, Mart<strong>in</strong> ; Rice, David ; Foemmel, Matthew: Patterns<br />
of Enterprise Application Architecture. Addison-Wesley Longman,<br />
Amsterdam, 2002 (A Mart<strong>in</strong> Fowler Signatur Book). – 560<br />
S. – ISBN 0321127420<br />
[Fus97] Fussell, Mark L.: Foundations of Object Relational<br />
<strong>Mapp<strong>in</strong>g</strong>. http://www.chimu.com/publications/objectRelational/<br />
objectRelational.pdf. Version: Juli 1997<br />
49
Literaturverzeichnis 50<br />
[GHJV04] Gamma, Erich ; Helm, Richard ; Johnson, Ralph ; Vlissides,<br />
John: Entwurfsmuster: Elemente wiederverwendbarer objektorientierter<br />
Software. Addison-Wesley, München, 2004. – 479 S. –<br />
ISBN 3827321999<br />
[KB04] K<strong>in</strong>g, Gav<strong>in</strong> ; Bauer, Christian: Hibernate <strong>in</strong> Action: Practical<br />
Object/Relational <strong>Mapp<strong>in</strong>g</strong>. Mann<strong>in</strong>g, 2004. – 408 S. – ISBN<br />
193239415X<br />
[KBK08] Kuate, Pierre ; Bauer, Christian ; K<strong>in</strong>g, Gav<strong>in</strong>: Nhibernate<br />
<strong>in</strong> Action. MEAP 2008-08-04. Mann<strong>in</strong>g, 2008. – 560 S. – ISBN<br />
1932394923<br />
[MN02] Moses, Daniel ; Nowak, Johannes: Programmieren unter .net.<br />
C# Edition. Franzis Verlag, 2002. – 645 S. – ISBN 3772372244<br />
[Nil02] Nilsson, Jimmy: InformIT: The Cost of GUIDs as Primary<br />
Keys > Natural or Surrogate Keys. http://www.<strong>in</strong>formit.com/<br />
articles/article.aspx?p=25862. Version: März 2002. – Letzter Zugriff:<br />
2008-07-04 16:11<br />
[Nil06] Nilsson, Jimmy: Apply<strong>in</strong>g Doma<strong>in</strong>-Driven Design and Patterns:<br />
With Examples <strong>in</strong> C# and .<strong>NET</strong>. Addison-Wesley Longman,<br />
Amsterdam, 2006. – 576 S. – ISBN 0321268202<br />
[Pap07] Papa, John: Datenpunkte: Übersicht über <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>.<br />
http://msdn.microsoft.com/de-de/magaz<strong>in</strong>e/cc163399.<br />
aspx. Version: Juli 2007. – Letzter Zugriff: 2008-09-04 18:20<br />
[RNG + 04] Rob<strong>in</strong>son, Simon ; Nagel, Christian ; Glynn, Jay ; Allen,<br />
K. S. ; Cornes, Ollie ; Greenvoss, Zach ; Harvey, Burton ;<br />
Sk<strong>in</strong>ner, Morgan ; Watson, Karli: Professional C sharp. 2nd<br />
Edition. Wiley & Sons, 2004. – 1270 S. – ISBN 1861007043<br />
[Sch07] Schwichtenberg, Dr. H.: iX - 07.06.06 - Microsoft und das<br />
OR-<strong>Mapp<strong>in</strong>g</strong>: Es bleibt kurios. http://www.heise.de/ix/Microsoftund-das-OR-<strong>Mapp<strong>in</strong>g</strong>-Es-bleibt-kurios--/blog/artikel/73937.<br />
Version: Juni 2007. – Letzter Zugriff: 2008-08-30 13:57<br />
[Sch08] Schwichtenberg, Dr. H.: iX - 28.08.08 - LINQ-to-SQL versus<br />
<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>. http://www.heise.de/ix/LINQ-to-<br />
SQL-versus-<strong>ADO</strong>-<strong>NET</strong>-<strong>Entity</strong>-<strong>Framework</strong>--/blog/artikel/115087.<br />
Version: August 2008. – Letzter Zugriff: 2008-08-29 12:12
Web-Referenzen<br />
[1] Allch<strong>in</strong>, J. : Jim Allch<strong>in</strong>: Microsoft Professional Developers<br />
Conference 2005. http://www.microsoft.com/presspass/exec/Jim/09-<br />
13PDC2005.mspx. Version: Sept. 2005. – Letzter Zugriff: 2008-06-18<br />
14:03<br />
[2] Apple: WebObjects Enterprise Objects Programm<strong>in</strong>g Guide: Introduction<br />
to WebObjects Enterprise Objects Programm<strong>in</strong>g Guide.<br />
http://developer.apple.com/documentation/WebObjects/Enterprise_<br />
Objects/About/chapter_1_section_1.html. Version: Jul. 2007. – Letzter<br />
Zugriff: 2008-01-19 09:45<br />
[3] Bauer, C. : [Hibernate] NHibernate jo<strong>in</strong>s Hibernate at JBoss<br />
Inc. http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/<br />
msg05094.html. – Letzter Zugriff: 2008-09-03 12:16<br />
[4] Ben-Ami, N. : <strong>ADO</strong>.<strong>NET</strong> team blog : Update Model From<br />
DB. http://blogs.msdn.com/adonet/archive/2008/04/01/update-modelfrom-db.aspx.<br />
Version: Apr. 2008. – Letzter Zugriff: 2008-09-15 13:52<br />
[5] Blakeley, J. ; Campbell, D. ; Gray, J. ; Muralidhar, S. ; Nori,<br />
A. : Next-Generation Data Access: Mak<strong>in</strong>g the Conceptual Level<br />
Real. http://msdn.microsoft.com/en-us/library/aa730866(vs.80).aspx.<br />
Version: Jun. 2006. – Letzter Zugriff: 2008-06-18 14:14<br />
[6] Bouma, F. : Why change-track<strong>in</strong>g has to be part of an entity object<br />
- Frans Bouma’s blog. http://weblogs.asp.net/fbouma/archive/2007/<br />
04/03/why-change-track<strong>in</strong>g-has-to-be-part-of-an-entity-object.aspx.<br />
Version: Apr. 2007. – Letzter Zugriff: 2008-07-14 15:25<br />
[7] Devart: Devart News: New Software Releases, Company News<br />
and Press Releases. http://devart.com/news/2008/directs475.html.<br />
Version: Aug. 2008. – Letzter Zugriff: 2008-09-14 13:51<br />
[8] Esposito, D. : ObjectSpaces - D<strong>in</strong>o Esposito’s WebLog. http://weblogs.<br />
asp.net/despos/archive/2004/01/21/61052.aspx. Version: Jan. 2004. –<br />
Letzter Zugriff: 2008-06-18 13:16<br />
51
Web-Referenzen 52<br />
[9] ICSharpCode: SharpDevelop @ic#code. http://sharpdevelop.net/<br />
OpenSource/SD/. Version: Jul. 2008. – Letzter Zugriff: 2008-07-10 13:19<br />
[10] Jones, L. : <strong>ADO</strong>.<strong>NET</strong> team blog : Update Model – a Question of Identity<br />
– Part 1 of 3. http://blogs.msdn.com/adonet/archive/2008/07/21/<br />
update-model-a-question-of-identity-part-1-of-3.aspx. Version: Jul. 2008.<br />
– Letzter Zugriff: 2008-09-15 13:45<br />
[11] Kaufmann, M. : <strong>ADO</strong>.<strong>NET</strong> team blog : EDM Tools | Options (Part<br />
1 of 4). http://blogs.msdn.com/adonet/archive/2008/06/20/edm-toolsoptions-part-1-of-4.aspx.<br />
– Letzter Zugriff: 2008-08-06 10:37<br />
[12] Kovacs, J. : James Kovacs’ Weblog - Enabl<strong>in</strong>g Intellisense<br />
for NHibernate. http://www.jameskovacs.com/blog/<br />
Enabl<strong>in</strong>gIntellisenseForNHibernate.aspx. Version: Okt. 2007. – Letzter<br />
Zugriff: 2008-09-14 18:56<br />
[13] Kulkarni, D. ; Bolognese, L. ; Warren, M. ; Hejlsberg, A. ;<br />
George, K. : LINQ to SQL: .<strong>NET</strong> Language-Integrated Query for Relational<br />
Data. http://msdn.microsoft.com/en-us/library/bb425822.aspx.<br />
Version: März 2007. – Letzter Zugriff: 2008-09-02 11:02<br />
[14] Mallalieu, T. : <strong>Entity</strong> <strong>Framework</strong> Design : Transparency <strong>in</strong> the<br />
design process. http://blogs.msdn.com/efdesign/archive/2008/06/23/<br />
transparency-<strong>in</strong>-the-design-process.aspx. – Letzter Zugriff: 2008-07-24<br />
22:31<br />
[15] Mallalieu, T. : <strong>Entity</strong> <strong>Framework</strong> Design : Initial POCO Design<br />
1-Pager. http://blogs.msdn.com/efdesign/archive/2008/06/24/<strong>in</strong>itialpoco-design-1-pager.aspx.<br />
Version: Jun. 2008. – Letzter Zugriff: 2008-<br />
07-24 22:26<br />
[16] Mallalieu, T. : Tim Mallalieu’s Blog. : To Lazy Load or not to Lazy<br />
load? http://blogs.msdn.com/timmall/archive/2008/06/24/to-lazy-loador-not-to-lazy-load.aspx.<br />
Version: Jun. 2008. – Letzter Zugriff: 2008-07-<br />
24 21:54<br />
[17] Mallalieu, T. : Tim Mallalieu’s Blog. : Vote of No Confidence.http://blogs.msdn.com/timmall/archive/2008/06/24/vote-of-noconfidence.aspx.<br />
Version: Jun. 2008. – Letzter Zugriff: 2008-07-24 22:01<br />
[18] Microsoft: <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> and LINQ to Entities<br />
(Pre-release) - MSDN Forums. http://forums.microsoft.com/MSDN/<br />
ShowForum.aspx?ForumID=533\&SiteID=1. – Letzter Zugriff: 2008-09-<br />
02 17:15
Web-Referenzen 53<br />
[19] Microsoft: Customiz<strong>in</strong>g Objects (<strong>Entity</strong> <strong>Framework</strong>). http://msdn.<br />
microsoft.com/en-us/library/bb738612.aspx. – Letzter Zugriff: 2008-10-<br />
28 09:36<br />
[20] Microsoft: <strong>Entity</strong> <strong>Framework</strong> Design. http://blogs.msdn.com/<br />
efdesign/default.aspx. – Letzter Zugriff: 2008-07-25 11:56<br />
[21] Microsoft: <strong>Entity</strong> <strong>Framework</strong> Features. http://msdn.microsoft.com/<br />
en-us/library/bb896338.aspx. – Letzter Zugriff: 2008-07-21 14:36<br />
[22] Microsoft: How to: Implement Custom Data Class Interfaces (<strong>Entity</strong><br />
<strong>Framework</strong>). http://msdn2.microsoft.com/en-us/library/bb738453.aspx.<br />
– Letzter Zugriff: 2008-06-17 15:56<br />
[23] Microsoft: Reference Source Service. http://www.microsoft.com/<br />
resources/sharedsource/referencesource.mspx. – Letzter Zugriff: 2008-09-<br />
04 10:14<br />
[24] Microsoft: Sav<strong>in</strong>g Changes and Manag<strong>in</strong>g Concurrency (<strong>Entity</strong><br />
<strong>Framework</strong>). http://msdn.microsoft.com/en-us/library/bb738618.aspx. –<br />
Letzter Zugriff: 2008-07-21 14:38<br />
[25] Microsoft: Schemas and <strong>Mapp<strong>in</strong>g</strong> Specification (<strong>Entity</strong> <strong>Framework</strong>).<br />
http://msdn.microsoft.com/en-us/library/bb399604.aspx. – Letzter Zugriff:<br />
2008-09-04 17:51<br />
[26] Microsoft: Visual Studio 2008 and .<strong>NET</strong> <strong>Framework</strong> 3.5 Service Pack<br />
1. http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx. –<br />
Letzter Zugriff: 2008-09-02 11:20<br />
[27] Microsoft: The <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> Overview. http://<br />
msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx. Version: Jun.<br />
2006. – Letzter Zugriff: 2008-07-10 10:50<br />
[28] Microsoft: Download details: Visual Studio 2008 Service Pack<br />
1 (Installer). http://www.microsoft.com/downloads/details.aspx?<br />
familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E\&displaylang=en.<br />
Version: Aug. 2008. – Letzter Zugriff: 2008-09-02 11:37<br />
[29] Microsoft: Download details: Visual Studio 2008 Service Pack 1 (iso).<br />
http://www.microsoft.com/downloads/details.aspx?familyid=27673C47-<br />
B3B5-4C67-BD99-84E525B5CE61\&displaylang=en. Version: Aug.<br />
2008. – Letzter Zugriff: 2008-09-02 11:37<br />
[30] Microsoft: Download details: VS 2008 Service Pack Preparation Tool.<br />
http://www.microsoft.com/downloads/details.aspx?familyid=A494B0E0-<br />
EB07-4FF1-A21C-A4663E456D9D\&displaylang=en. Version: Aug.<br />
2008. – Letzter Zugriff: 2008-09-02 11:38
Web-Referenzen 54<br />
[31] Microsoft: The LINQ Project. http://msdn.microsoft.com/en-us/<br />
netframework/aa904594.aspx. Version: Jul. 2008. – Letzter Zugriff: 2008-<br />
07-10 09:20<br />
[32] Microsoft: Overview: <strong>ADO</strong>.<strong>NET</strong> Data Services. http://msdn.<br />
microsoft.com/en-us/library/cc956153.aspx. Version: Aug. 2008. – Letzter<br />
Zugriff: 2008-09-28 15:36<br />
[33] Mono: Ma<strong>in</strong> Page - Mono. http://www.mono-project.com/Ma<strong>in</strong>_Page.<br />
Version: Jul. 2008. – Letzter Zugriff: 2008-07-10 13:08<br />
[34] Noras, A. : Anders Noras’ Blog : IPoco? http://andersnoras.com/<br />
blogs/anoras/archive/2007/07/03/ipoco.aspx. Version: Jul. 2007. – Letzter<br />
Zugriff: 2008-09-23 23:15<br />
[35] ODMBS.OG: ODBMS.ORG :: Object Database (ODBMS) | Object-<br />
Oriented Database (OODBMS) | Free Resource Portal. http://www.<br />
odbms.org/odmg.html. Version: Jul. 2008. – Letzter Zugriff: 2008-07-14<br />
13:47<br />
[36] Oracle: Oracle 11g, Siebel, PeopleSoft | Oracle, The World’s Largest<br />
Enterprise Software Company. http://www.oracle.com/<strong>in</strong>dex.html.<br />
– Letzter Zugriff: 2008-09-14 18:03<br />
[37] Oracle: Oracle TopL<strong>in</strong>k. http://www.oracle.com/technology/<br />
products/ias/topl<strong>in</strong>k/<strong>in</strong>dex.html. Version: Jun. 2008. – Letzter Zugriff:<br />
2008-06-17 16:37<br />
[38] PostgreSQL: PostgreSQL: The world’s most advanced open source<br />
database. http://www.postgresql.org/. – Letzter Zugriff: 2008-09-14<br />
18:47<br />
[39] RedHat: Chapter 16. Toolset Guide. http://www.hibernate.org/hib_<br />
docs/nhibernate/1.2/reference/en/html/toolsetguide.html. – Letzter Zugriff:<br />
2008-10-26 16:47<br />
[40] RedHat: hibernate.org - Databases supported by NHibernate. http:<br />
//www.hibernate.org/361.html. – Letzter Zugriff: 2008-09-03 13:38<br />
[41] RedHat: hibernate.org - Hibernate. http://www.hibernate.org/. – Letzter<br />
Zugriff: 2008-09-12 19:45<br />
[42] RedHat: hibernate.org - NHibernate Resources. http://www.hibernate.<br />
org/365.html. – Letzter Zugriff: 2008-01-06 00:04<br />
[43] RedHat: hibernate.org - Road Map. http://www.hibernate.org/357.<br />
html#A14. – Letzter Zugriff: 2008-09-03 13:31
Web-Referenzen 55<br />
[44] RedHat: jboss.org: community driven. http://www.jboss.org/. – Letzter<br />
Zugriff: 2008-09-03 11:56<br />
[45] RedHat: redhat.com | Home. https://www.redhat.com/. – Letzter<br />
Zugriff: 2008-09-03 11:57<br />
[46] RedHat: hibernate.org - NHibernate for .<strong>NET</strong>. http://www.hibernate.<br />
org/343.html. Version: Jan. 2008. – Letzter Zugriff: 2008-01-05 23:39<br />
[47] Sceppa, D. : <strong>ADO</strong>.<strong>NET</strong> team blog : SQLite’s <strong>ADO</strong>.<strong>NET</strong><br />
Provider Supports the <strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong>! http:<br />
//blogs.msdn.com/adonet/archive/2008/09/06/sqlite-s-ado-netprovider-supports-the-ado-net-entity-framework.aspx.<br />
Version: Sept.<br />
2008. – Letzter Zugriff: 2008-09-14 18:07<br />
[48] Security, A. A.: SQL Anywhere 11: Schneller Support für<br />
<strong>ADO</strong>.<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> und LINQ - All About SECURI-<br />
TY. http://www.all-about-security.de/security-artikel/applikations-hostsicherheit/backend-systeme-datenbanken/artikel/6784-sql-anywhere-<br />
11-schneller-support-fuer-adonet-entity-framew/. – Letzter Zugriff:<br />
2008-08-06 18:53<br />
[49] Simmons, D. : system.data.objects dev guy : EF Persistence Ignorance<br />
Recap. http://blogs.msdn.com/dsimmons/archive/2007/09/26/efpersistence-ignorance-recap.aspx.<br />
Version: Sept. 2007. – Letzter Zugriff:<br />
2008-01-14 21:27<br />
[50] Simmons, D. : system.data.objects dev guy : "June"CTP of the<br />
<strong>Entity</strong> <strong>Framework</strong> is f<strong>in</strong>ally out. http://blogs.msdn.com/dsimmons/<br />
archive/2007/07/03/june-ctp-of-the-entity-framework-is-f<strong>in</strong>ally-out.aspx.<br />
Version: Jul. 2007. – Letzter Zugriff: 2008-09-15 11:58<br />
[51] Simmons, D. ; NTDeveloper ; Hoffman, K. : Persistence Ignorance<br />
<strong>in</strong> the <strong>Entity</strong> <strong>Framework</strong> - MSDN Forums. http://forums.<br />
microsoft.com/MSDN/ShowPost.aspx?PostID=1339491\&SiteID=1.<br />
Version: März 2007. – Letzter Zugriff: 2008-09-15 13:24<br />
[52] Smith, D. : A Brief History of TopL<strong>in</strong>k. http://www.oracle.com/<br />
technology/tech/java/newsletter/articles/topl<strong>in</strong>k/history_of_topl<strong>in</strong>k.<br />
html. Version: Jun. 2008. – Letzter Zugriff: 2008-06-17 16:32<br />
[53] SQLite: SQLite Home Page. http://www.sqlite.org/. – Letzter Zugriff:<br />
2008-09-14 18:21<br />
[54] SunMicrosystems: MySQL :: Die populärste Open-Source-Datenbank<br />
der Welt. http://www.mysql.de/. – Letzter Zugriff: 2008-09-14 18:23
Web-Referenzen 56<br />
[55] SunMicrosystems: Java Persistence API. http://java.sun.com/<br />
javaee/technologies/persistence.jsp. Version: Jun. 2008. – Letzter Zugriff:<br />
2008-06-18 12:35<br />
[56] Team, A. : <strong>ADO</strong>.<strong>NET</strong> team blog : What’s New <strong>in</strong> the SP1 Beta?http://blogs.msdn.com/adonet/archive/2008/05/12/what-s-new-<strong>in</strong>the-sp1-beta.aspx?CommentPosted=true#commentmessage.<br />
– Letzter<br />
Zugriff: 2008-07-24 22:54<br />
[57] Team, A. : <strong>ADO</strong>.<strong>NET</strong> team blog : Third Party Provider Support for the<br />
<strong>Entity</strong> <strong>Framework</strong> RTM. http://blogs.msdn.com/adonet/archive/2008/<br />
08/11/third-party-provider-support-for-the-entity-framework-rtm.aspx.<br />
Version: Aug. 2008. – Letzter Zugriff: 2008-09-02 16:25<br />
[58] Team, A. : Project Astoria Team Blog. http://blogs.msdn.com/<br />
astoriateam/. – Letzter Zugriff: 2008-09-28 15:27<br />
[59] TechTalk: Genome > Home. http://www.genom-e.com/.<br />
Version: Jun. 2008. – Letzter Zugriff: 2008-06-17 19:39<br />
[60] TechTalk: Welcome @ TechTalk. http://web.techtalk.at/.<br />
Version: Sept. 2008. – Letzter Zugriff: 2008-09-02 15:56<br />
[61] Unbekannt: Hibernate History at SourceForge.net. http://sourceforge.<br />
net/news/?group_id=40712. – Letzter Zugriff: 2008-09-03 11:30<br />
[62] Unbekannt: Interview with Gav<strong>in</strong> K<strong>in</strong>g, founder of Hibernate. :: JavaFree.<br />
http://www.javafree.org/content/view.jf?idContent=3. – Letzter<br />
Zugriff: 2008-09-03 11:09<br />
[63] Unbekannt: System.Data.SQLite. http://sqlite.phxsoftware.com/. –<br />
Letzter Zugriff: 2008-09-11 19:03<br />
[64] Unbekannt: <strong>ADO</strong> .<strong>NET</strong> <strong>Entity</strong> <strong>Framework</strong> Vote of No Confidence.http://efvote.wufoo.com/forms/ado-net-entity-framework-voteof-no-confidence/.<br />
Version: Jun. 2008. – Letzter Zugriff: 2008-06-24<br />
23:46<br />
[65] Whitehead, N. : Hibernate Jo<strong>in</strong>s JBoss Group. http://www.<br />
theserverside.net/discussions/thread.tss?thread_id=21482. – Letzter Zugriff:<br />
2008-09-03 11:45