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

Seite 4: Faules und fleißiges Laden

Inhaltsverzeichnis

Die Definition der Abfrage ist aber noch nicht alles, was über die zu ladenden Objekte entscheidet. Ausschlaggend für die Leistungsfähigkeit von ORMs ist, wann sie verbundene Objekte laden. Wer zu einer Rechnung sofort alle Positionen und die dazugehörigen Artikelstammdaten lädt, bläht unter Umständen die Anwendung unnötig auf. Holt das Programm die Daten jedoch nicht, muss es sie beim Zugriff auf eine Objektreferenz nachladen. Das wird Lazy Loading, Deferred Loading oder Delayed Loading genannt, im Unterschied zum Eager Loading (alias Immediate Loading). Lazy Loading ist in beiden Frameworks die Voreinstellung, Eager Loading optional.

LINQ-to-SQL lädt allerdings die verbundenen Objekte "transparent" (also automatisch) nach, während EF nur nach expliziter Anforderung tätig wird. Man muss mit IsLoaded() prüfen und dann explizit die Load()-Methode aufrufen. Diese Lästigkeit ist kein Bug, sondern eine bewusste Design-Entscheidung der Entwickler. Sie wollten erreichen, dass die Anwender sich des Nachladens bewusst sind. Da es aber auch gute Gründe für transparentes Laden gibt, wird Microsoft ab .NET 4.0 im EF sowohl explizites als auch transparentes Lazy Loading bieten. Beim Eager Loading gibt es noch einen Unterschied bei der Handhabung: Im EF kann man es für jede einzelne Abfrage definieren, während in LINQ-to-SQL die Einstellung global für den Datenkontext gilt. Hier punktet also EF wieder.

Für verteilte Systeme ist die Serialisierbarkeit ein entscheidendes Thema. EF bietet anders als LINQ-to-SQL die Serialisierung kompletter Objektbäume. Bei LINQ-to-SQL sind Assoziationen nicht serialisierbar, sondern nur einzelne Objekte ohne die über Navigationsattribute verbundenen Objekte.

Solange ein Objekt im selben Prozess wie der Kontext lebt, überwacht er alle Änderungen an ihm (Change Tracking). Dies wächst sich zu einem Problem aus, wenn die Geschäftsobjekte länger leben als der ORM-Container, zum Beispiel in Webanwendungen oder anderen zustandslosen Anwendungsservern. Bei Disconnected Objects (alias Detached Objects) können von Haus aus weder LINQ-to-SQL noch das Entity Framework die Änderungen nachverfolgen. Im Klartext heißt dies: Überträgt man per Webservice 1000 Rechnungsobjekte an den Client, gibt es keine eingebaute Funktion, um nur die geänderten Objekte zurückzuübertragen. Für das Entity Framework existiert immerhin die Lösung EntityBag auf dem Quellcodeportal Codeplex.

Diese Unzulänglichkeit der ORM-Werkzeuge in verteilten Szenarien löst Microsoft (zukünftig) in Zusatzprodukten wie den ADO.NET Data Services und den .NET RIA Services. Eigentlich könnten die Anwender erwarten, dass die clientseitige Änderungsverfolgung losgelöster Objekte im Produktkern enthalten sind. Denn Data Services und RIA Services haben eine zu starke Bindung an bestimmte Transport- und Serialisierungsmechanismen.