Verwirrung um ORM: LINQ-to-SQL oder ADO.NET Entity Framework?

Seite 2: Datenbanken und Mappings

Inhaltsverzeichnis

Microsoft liefert in beiden Fällen nur Treiber für den eigenen SQL Server. Bei ADO.NET unterstützt es jedoch die Erstellung von Treibern durch andere Anbieter, weshalb es Anbindungen für alle namhaften relationalen Datenbanken gibt. Bei LINQ-to-SQL hingegen blockiert Microsoft die Erstellung neuer Treiber ("No public provider model is available. At this time, LINQ-to-SQL supports SQL Server and SQL Server Compact 3.5 only", heißt es in der LINQ-to-SQL-FAQ). Dies bezieht sich wohlgemerkt nur auf die ORM-Funktionen im engeren Sinne; die Erstellung allgemeiner LINQ-Provider ist wieder dokumentiert, sodass es zahlreiche Treiber für Nicht-Datenbanken gibt. Die Firma Devart liefert zudem LINQ-to-SQL-ähnliche Provider für Oracle, MySQL, PostgreSQL und SQLite.

Neben Reverse Engineering (alias Database First, das heißt die Erstellung von Geschäftsobjekten aus Datenbanken) kennt LINQ-to-SQL Forward Engineering (alias Code-First, das heißt die Erstellung der Datenbank aus Geschäftsobjekten). EF bietet nur Reverse Engineering. Erst in der zweiten Version, die mit dem .NET Framework 4.0 Anfang 2010 erscheinen wird, soll es auch Forward Engineering beherrschen.

LINQ-to-SQL gestattet fast nur die 1:1-Abbildung zwischen Tabellen und Objekten. Einzige Ausnahme davon ist die Vererbung, bei der es Filtered Mapping anbietet. Das Entity Framework ermöglicht mehr Abbildungen. Insbesondere kann es die im relationalen Modell notwendigen Zwischentabellen in n:m-Beziehungen eliminieren und unterstützt bei der Vererbung Vertical Mapping (alias Joined Mapping, Inheritance Table per Class oder Vertical Polymorphism) sowie Horizontal Mapping (alias Table per Subclass, Horizontal Polymorphism). Allerdings ist Voraussetzung, dass die "erbenden" Tabellen den gleichen Primärschlüssel besitzen. Mit Fremdschlüsseln darf man hier nicht arbeiten.

LINQ-to-SQL arbeitet direkt auf dem Datenbankschema, nicht auf dem konzeptuellen Modell, das bei der Entity-Relationship-Modellierung (ERM) verwendet wird. EF bietet Mapping auch auf Tabellenebene (das heißt auch ohne objekt-relationales Mapping). LINQ-to-SQL kennt das nicht. Dort kann man das Mapping wahlweise im Programmcode durch Annotationen oder in einer externen XML-Datei erstellen. EF akzeptiert dafür nur XML-Dateien.

LINQ-to-SQL bietet als Abfragesprache LINQ oder SQL. EF kennt LINQ sowie das datenbankneutrale Entity SQL (eSQL). Dieser SQL-Dialekt bietet nur den SELECT-Befehl. Mit eSQL formuliert man Abfragen auf der abstrakteren Datenmodellierungsebene, die man aus dem ER-Modell kennt. Ein LINQ-Befehl ist immer eine statische Abfrage: Sie hat stets dieselben Konstrukte; man kann nicht zwei oder vier Bedingungen im WHERE angeben, sondern es muss immer genau dieselbe Anzahl sein. Dynamische LINQ-Befehle kann man aber in beiden ORM-Werkzeugen formulieren: im EF durch die "Query Builder Methods" in der Klasse ObjectQuery und in LINQ-to-SQL durch die Klasse DynamicQueryable, die in den mit Visual Studio 2008 gelieferten Beispielen enthalten ist.

Dennoch hat in dieser Kategorie LINQ-to-SQL einen Vorteil, denn es unterstützt datenbankspezifisches SQL. Das kann gegenüber einer datenbankneutralen Objektabfragesprache Vorteile beim Optimieren bringen. Denn bei ihr erzeugt das ORM-Werkzeug automatisiert SQL-Befehle, und der Entwickler ist diesem Generator "ausgeliefert". Eine Objektabfragesprache ist also nichts für "SQL-Kontroll-Fetischisten".

Sowohl LINQ-to-SQL als auch EF unterstützen die Vorkompilierung von LINQ-Abfragen. Das Übersetzen von LINQ in SQL benötigt einige Zeit. Vorkompilieren gleichartiger Abfragen kann die Leistung erheblich steigern (vgl. Abbildung 2).