ITMAGAZINE Objektrelationale Brücke für .NET von Urs Bertschy 10. Oktober 2008 - Nach mehreren gescheiterten Anläufen kann Microsoft mit dem Entity Framework nun endlich mit einem objektrelationalen Mapper für ADO.NET aufwarten. Die fehlende Object/Relation-Mapping-Technologie (ORM) war lange Zeit eine der grossen Schwächen im .NET-Framework. Nachdem man bei Microsoft das Bedürfnis nach einer ORM-Lösung in der Anfangsphase von .NET schlichtweg verschlafen oder ignoriert hat, unternahm man vor einigen Jahren mit ObjectSpaces und WinFS gleich zwei Anläufe in diesem Bereich. Mit beiden Ansätzen scheiterte der Branchenriese kläglich, und man musste in den Redmond-Labors praktisch wieder von vorne anfangen. Paradoxerweise bietet Microsoft inzwischen gleich zwei objektrelationale Mapper parallel an. Nachdem mit LINQ to SQL im Rahmen von Visual Studio 2008 (siehe InfoWeek 11/08) bereits eine relativ einfache ORM-Lösung für den SQL-Server eingeführt wurde, steht seit August mit dem Release des SP1 für das .NET-Framework 3.5 und Visual Studio 2008 nun mit dem ADO.NET Entity Framework (ADO.NET EF) eine umfangreichere und vor allem auch datenbankunabhängige objektrelationale Technologie bereit. Was ist ORM? Ziel des objektrelationalen Daten-Mapping ist es, die unter Fachkreisen als Impedance Mismatch oder Semantic Gap genannte Problematik auszuräumen. Wer eine objektorientierte Programmiersprache einsetzt, möchte durchgängig mit Objekten arbeiten, auch dann wenn es um die Verarbeitung von Daten geht, welche in einer relationalen Datenbank gespeichert sind. Ziel dabei ist es, mit Geschäftsobjekten (auch Business Objects oder Geschäftsentitäten) zu arbeiten, die möglichst der Realität (Rechnung, Kunde, Artikel etc.) entsprechen. Das bringt gleich eine Reihe von Vorteilen mit sich: Mit Geschäftsobjekten lässt es sich aus programmiertechnischer Sicht – vor allem auch im Team – intuitiver arbeiten. Ausserdem lassen sich n:m-Beziehungen einfacher abbilden und es kann auf typische objektorientierte Techniken wie die Vererbung zurückgegriffen werden. Die Problematik dabei ist allerdings, dass Daten in der überwiegenden Zahl der verwendeten Datenbanken nicht in Form von Objekten, sondern normalisiert in relational verknüpften Tabellen abgelegt werden. Die Daten für eine Rechnung können beispielsweise über verschiedene Tabellen hinweg verteilt sein. Die Daten eines Objekts sind daher in den meisten Fällen nicht direkt auf die Tabellenstruktur übertragbar. Und genau hier kommt das objektrelationale Mapping ins Spiel: Es fungiert als Übersetzer zwischen relationalen Tabellen und den gewünschten Geschäftsobjekten. Neben den Vorzügen, welche das Objektmodell mit sich bringt, hat der Einsatz eines O/R-Mapper einen weiteren Vorteil: Der Entwickler muss weniger Datenzugriffscode schreiben. Für das Persistieren der Daten ist der O/R-Mapper zuständig, der den notwendigen SQL-Code im Hintergrund generiert und an die Datenbank absetzt. Das bedeutet auch, dass sich der verwendete Datenbankserver beim Einsatz einer ORM-Lösung relativ einfach austauschen lässt. Das Entity Framework im Überblick Das Entity Framework im Überblick Das ADO.NET Entity Framework setzt, wie sein Name bereits erahnen lässt, auf ADO.NET auf. Es erweitert die .NET-Datenzugriffstechnologie um eine weitere Abstraktionsschicht, welche die Kluft zwischen Tabellen und Geschäftsobjekten überwinden soll (siehe Diagramm «Die Architektur des ADO.NET Entity Framework»). Neben den Object Services, welche hauptsächlich für die Verwaltung der Geschäftsobjekte zuständig sind, kommt dem Entity Data Model (EDM) eine zentrale Rolle zu. Hier werden die Geschäftsklassen modelliert sowie das eigentliche Mapping zwischen den Objekten und den relationalen Datenstrukturen festgelegt (siehe Diagramm «Das Entity Data Model»). Das Entity Data Model setzt sich aus drei verschiedenen Modellen zusammen: - Conceptual Model (DSDL): Im konzeptionellen Modell werden die Geschäftsentitäten und deren Beziehungen definiert, wie sie auf der Geschäftsebene der Anwendung benötigt werden. Eine eigentliche Verbindung zur physikalischen Struktur in der Datenbank existiert in diesem Modell nicht. Das konzeptionelle Modell unterstützt auch komplexe Datentypen und die Vererbung. Die Geschäftsobjekte werden vom Entity Framework auf Basis dieses Modells generiert. - Storage Model (SSDL): Das Speichermodell entspricht dem zugrundeliegenden Datenbankschema und beschreibt, wo und wie die Daten physisch (z.B. in welchen Tabellen und Spalten) abgelegt werden. Das Storage Model unterstützt dabei auch Stored Procedures und Views zur Aktualisierung und Abfrage. - Mapping Model (MSL): Im Zuordnungsmodell wird beschrieben, wie die Daten zwischen den Business-Objekten des konzeptionellen Modells in das Speichermodell überführt werden müssen. Das Entity Data Model Wizards helfen bei der Modellierung Die verschiedenen Modelle im EDM werden ausschliesslich in XML beschrieben. Microsoft stellt allerdings Wizards und ein visuelles Modellierungswerkzeug (EF Designer) für Visual Studio 2008 zur Verfügung, mit deren Hilfe die Definitionen der drei Modelle relativ einfach von der Hand gehen. Dabei wird jeweils nach dem folgendem Schema vorgegangen: Ausgehend von einer Datenbank werden mit Hilfe eines Wizard die für das gewünschte Modell benötigten Tabellen, Views und Stored Procedures selektiert (siehe Bild 1). Anschliessend generiert Visual Studio das konzeptionelle Modell. Nun kann man über den visuellen Designer Änderungen und Erweiterungen am Modell vornehmen (Bild 2). Alternativ kann auch mit einem leeren Modell gestartet werden. In diesem Fall müssen die Entitäten sowie die Mappings auf die Datenbanktabellen von Hand angelegt werden. Der entsprechende Source-Code für die Geschäftsklassen wird jeweils On-the-Fly in der entsprechenden Codebehind-Datei nachgetragen. Spätere Änderungen an der Datenbank können mit Hilfe eines Update Wizard im Modell aktualisiert werden, ohne dass dabei die bereits manuell durchgeführten Anpassungen überschrieben werden. Den umgekehrten Weg des sogenannten Forward Engineering wird vom ADO.NET Entity Framework im Gegensatz zu anderen ORM-Lösungen auf dem Markt übrigens nicht unterstützt. Bei diesem Verfahren werden erst die Geschäftsklassen modelliert und anschliessend die relationalen Strukturen in der Datenbank generiert. Zugriff nach altem Muster Mit dem Entity Client und den Object Services stellt das ADO.NET Entity Framework gleich zwei Schnittstellen für die Arbeit mit den im EDM gespeicherten Datenmodellen bereit. Der Entity Client (EntityClient) ist den Datenprovidern sehr ähnlich, die man bereits aus ADO.NET (z.B. SQLClient) kennt. So werden Entity-Client-Abfragen beispielsweise ebenfalls mit einem Command-Objekt (EntityCommand) ausgeführt, das für die Verbindung zum EDM ein Connection-Objekt (EntityConnection) erfordert. Obwohl der Entity Client mit den Entitäten in EDM interagiert, werden keine Instanzen der Entitäten zurückgegeben. Statt dessen werden die Ergebnisse in Form eines DataReader-Objekts geliefert. Da SQL nicht auf die Verarbeitung von Objekten ausgelegt ist, stellt der Entity Client eine spezielle SQL-Erweiterung mit der Bezeichnung Entity SQL (eSQL) zur Verfügung. eSQL ist speziell auf die Abfrage von im EDM gespeicherten Modellen optimiert. So kann zum Beispiel auf umständliche Joins verzichtet werden, da die Relationen zwischen den Entitäten ja bereits im Modell beschrieben sind. Arbeiten mit Geschäftsobjekten Die volle ORM-Funktionalität kommt im ADO.NET Entity Framework erst bei der Verwendung der Object Services zum Tragen. Diese erlauben es, die im EDM definierten Entitäten in Form von instanzierten Geschäftsobjekten zu verwenden. Die Object Services sind zudem für die Persistierung der Business-Objekte verantwortlich und unterstützen dazu die typischen CRUD-Operationen (Create, Read, Update, Delete). Den für den Zugriff auf die Datenbank notwendigen SQL-Code wird dabei zur Laufzeit im Hintergrund dynamisch erzeugt. Ausserdem stellen die Object Services weitere wichtige ORM-Mechanismen zur Verfügung. Dazu gehören etwa die Überwachung von Veränderungen an den Daten (so dass beispielsweise nur die Änderungen in die Datenbank zurückgeschrieben werden müssen), Identity Resolution oder das Concurrency Handling. Interessant an den Object Services ist, dass hier neben eSQL auch mit LINQ to Entities gearbeitet werden kann. Damit kommt man in den Genuss sämtlicher Vorteile von LINQ wie beispielsweise IntelliSense, lesbarerer Code oder eine Fehlerprüfung durch den Compiler. ADO.NET EF versus LINQ to SQL Bei zwei gleichzeitigen O/R-Mappern aus demselben Haus drängt sich natürlich die Frage auf, wo die Unterschiede zwischen den beiden Lösungen liegen und welchen Mapper man für welchen Zweck einsetzen soll. Einer der gewichtigsten Unterschiede betrifft die Unterstützung der Datenbanken. Während bei LINQ to SQL ausschliesslich mit SQL Server ab Version 2000 (auch mit den Express-Editionen) gearbeitet werden kann, lässt das ADO.NET Entity Framework über ein offenes Providermodell die Einbindung von Datenbanksystemen anderer Anbieter zu. Neben Microsofts hauseigenem Provider für den SQL Server sind bereits Provider für Oracle, MySQL, SQLite, IBM DB2, PostgeSQL und einige andere Systeme erhältlich oder zumindest noch für dieses Jahr angekündigt. Da LINQ to SQL direkt auf dem Datenbankschema aufsetzt und mit dem konzeptionellen Modell auf eine wesentliche Abstraktions-ebene verzichtet wird, bietet das ADO.NET Entity Framework deutlich mehr Flexibilität beim Mapping und bei der Modellierung von Entities. Ein weiteres Manko von LINQ to SQL ist, dass Änderungen an den Datenbankstrukturen im generierten Modell nicht aktualisiert werden. Der Einsatz von LINQ to SQL macht deshalb vor allem in «einfacheren» Szenarien oder für RAD (Rapid Application Development) Sinn, wo die 1:1-Abbildung von Tabellen auf Klassen ausreicht. Gegenüber LINQ-to-SQL bietet das ADO.NET Entity Framework einige Vorteile, wie beispielsweise das Abbilden von n:m-Relationen, die automatische Aktualisierung des Modells bei Änderungen am Datenbankschema oder der Verwendung von komplexen Datentypen und Vererbung. Wegen des grösseren Funktionsumfangs und der höheren Flexibilität eignet sich das Entity Framework eher für den Enterprise-Einsatz – vor allem auch dann, wenn ein späterer Wechsel der darunterliegenden Datenbank nicht auszuschliessen ist. Die Architektur des ADO.NET Entity FramewoRks Kritik am Entity Framework In den letzten Monaten kam gegenüber dem ADO.NET Entity Framework immer wieder die Kritik auf, dass wichtige Aspekte einer ORM-Lösung gar nicht richtig umgesetzt würden. Vergangenen Juni hat sich gar eine Gruppe von Entwicklern zusammengerauft und eine Petition gestartet, mit der erreicht werden soll, dass Microsoft das Design des Entity Framework noch einmal gründlich überdenkt. Neben einer ganzen Reihe von technischen Details (z.B. das mangelhafte Lazy Loading) bemängelt die Gruppe vor allem die datenlastige Sichtweise des Framework. Dies würde Domain-getriebenes Modellieren (Objects-first-Prinzip), bei dem primär auf ein optimales Design von Geschäftsobjekten und erst in einem zweiten Schritt auf das Design des Datenbankschemas geachtet wird, praktisch unmöglich machen. Ausserdem wird in der Petition die fehlende Unterstützung des EF-Designers für die Entwicklung in Teams oder die mangelhafte Umsetzung von Test-Driven-Design-Prinzipien moniert. Das ADO.NET-Team hat auf die Petition reagiert und versprochen, die Ausmerzung der angeführten Mängel für den nächsten Release in Betracht zu ziehen. Version 2.0 des ADO.NET Entity Framework wird allerdings erst gemeinsam mit Visual Studio 10 erscheinen, das vermutlich nicht vor Ende 2009 auf den Markt kommen wird. Fazit Nach einigen Anlaufschwierigkeiten hat es Microsoft nun endlich geschafft, eine einigermassen solide ORM-Lösung für .NET zu liefern. Wie die breit abgestützte Kritik zeigt, handelt es sich beim ADO.NET Entity Framework um einen typischen 1.0-Release, der noch über einige Ecken und Kanten verfügt. Für Entwickler dürfte es sich trotzdem lohnen, sich bereits heute mit dem Entity Framework zu beschäftigen und für künftige Projekte in Betracht zu ziehen. Denn mittel- bis längerfristig dürfte sich bei Microsoft das Entity Framework als die bevorzugte ORM-Technologie – auch zugunsten von LINQ to SQL – durchsetzen. In Redmond scheint man grosse Pläne für den neuen Object Mapper zu haben und spricht davon, ADO.NET EF in künftigen Produkten wie zum Beispiel in den SQL Server zu integrieren. Copyright by Swiss IT Media 2017