11.12.2012 Aufrufe

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

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!