Als der vorliegende Artikel verfasst wurde, existierten vor allem zwei Quellen, die einen Blick in die Zukunft des Entity Frameworks erlaubten: Zum einen die Entity Framework CTP, die im Juni 2011 veröffentlicht wurde, und zum anderen die aktuelle Beta-Version von EntityFramework.Migrations, die Code Only um die Möglichkeit zum Migrieren von Datenbankschemata erweitert. Während die Neuerungen, die in der CTP zu finden sind, erst mit .NET 4.5 ausgeliefert werden, wird die Migrationskomponente unabhängig davon via NuGet zur Verfügung gestellt. Beim Evaluieren der CTP ist darauf zu achten, dass sie eine eigene .NET-Framework-Version mit sich bringt. Diese Version, die als Microsoft Entity Framework June 2011 CTP [1] bezeichnet wird, muss in den Projekteigenschaften ausgewählt werden (Abb. 1), damit die damit vorab bereitgestellten Möglichkeiten zur Verfügung stehen.

Unterstützung für Enums
Die Unterstützung für Enums durch das Entity Framework wurde in der Vergangenheit schmerzlich vermisst. Das wird sich nun ändern. Um eine Eigenschaft auf einen neuen Enum basieren zu lassen, bietet die betrachtete CTP den Kontextmenübefehl CONVERT TO ENUM (Abb. 2).

Nachdem dieser gewählt wurde, kann der Entwickler den Namen und die möglichen Werte des neuen Enums definieren (Abb. 3). Nach dem Anlegen findet sich dieser im Model Browser wieder. Sämtliche im Model befindlichen Enums können als Datentypen für Eigenschaften in Entitäten herangezogen werden. Dabei gilt es zu beachten, dass derzeit immer der hinter einem Enum-Wert stehende Integer direkt gemappt wird. Ein Abbilden dieser Werte auf Strings ist derzeit nicht möglich. Darüber hinaus gelten die folgenden Einschränkungen:
- Enum-basierte Eigenschaften können nicht als Schlüssel definiert werden.
- Enum-basierte Eigenschaften werden nicht von EntityParameter unterstützt.
- System.Enum.HasFlag wird nicht in LINQ-Abfragen unterstützt.
- EntityDataSource bietet nur eine teilweise Unterstützung für Enum-basierte Eigenschaften.
- Enum-basierte Eigenschaften können nicht für Bedingungen im konzeptionellen Modell herangezogen werden.
- Es können keine Standardwerte für Enum-basierte Eigenschaften im konzeptionellen Modell definiert werden.

Ein Beispiel für die Verwendung von Enums in Abfragen findet sich in Listing 1.
Listing 1
private void EnumDemo() { using (var ctx = new HotelDbContext()) { var hotels = ctx.Hotel .Where(h => h.Kategorie == HotelKategorie.Seminarhotel) .ToList(); foreach (var h in hotels) { Console.WriteLine(h.Bezeichnung + " " + h.Sterne); } } }
Geografische Datentypen
Auch die beiden mit SQL Server 2008 eingeführten geografischen Datentypen geography und geometry werden in Zukunft im Entity Framework Unterstützung finden. Als .NET-Gegenstück werden die Klassen DbGeography und DbGeometry herangezogen. Der Einsatz von DbGeography wird in Listing 2 veranschaulicht. Hier werden alle Hotels abgerufen, die sich in einem 50 Kilometer großen Radius um den durch location beschriebenen Punkt befinden. Die Verwendung von DbGeometry gestaltet sich analog dazu.
Listing 2
private static void GeoDemo() { var maxDistance = 50000; var location = DbGeography.Parse("POINT(47.103889 15.708333)"); using (var ctx = new HotelDbContext()) { var hotels = ctx .Hotel .Where(h => h.Koordinaten.Distance(location) <= maxDistance) .ToList(); foreach (var h in hotels) { Console.WriteLine(h.Bezeichnung + " " + h.Sterne); } } }
Table-Valued Functions
Während Stored Procedures seit der ersten Stunde durch das Entity Framework unterstützt werden, war dies bis dato bei Table-Valued Functions nicht der Fall. Auch diese Einschränkung wird bald der Vergangenheit angehören. Um in der betrachteten CTP eine Table-Valued Function zu mappen, ist für diese nach dem Reverse Engineering im Model Browser ein Function Import anzulegen (Abb. 4).

Damit die Funktion auch ausgewählt werden kann, ist die Option Function Import is Composable zu aktivieren. Anschließend kann der Entwickler die in der Datenbank hinterlegte Funktion direkt über eine entsprechende Methode anstoßen, die automatisch im Context eingerichtet wird, wie Listing 3 demonstriert.
Listing 3
private static void TVFDemo() { using (var ctx = new HotelDbContext()) { var hotels = ctx.GetHotelByRegion(3) .Where(h => h.Sterne > 3) .ToList(); foreach (var h in hotels) { Console.WriteLine(h.Bezeichnung + " " + h.Sterne); } } }
Dabei gilt zu beachten, dass die gesamte Abfrage, in die die datenbankseitige Funktion inkludiert ist, in der Datenbank ausgeführt wird. Beim Einsatz von Stored Procedures wäre das hingegen nicht der Fall. Die Definition der hier verwendeten Table-Valued Function zeigt Listing 4.
Listing 4
CREATE FUNCTION [dbo].[GetHotelByRegion] ( @regionId int ) RETURNS TABLE AS RETURN ( SELECT * from Hotel where RegionId = @regionId )