ASP.NET Dynamic Data in Visual Studio 2012 – Entity Framework

21. November 2012

ASP.NET Dynamic Data mit dem Entity Framework funktioniert in Visual Studio 2012 so gut wie in VS 2010. Im Prinzip… .

Hinweis: In diesem Beitrag werfe ich einen Blick auf das ADO.NET Entity Framework, LINQ 2 SQL folgt in einem eigenen Beitrag.

 

Wer seine Anwendung mit ASP.NET Dynamic Data bereits laufen hat, sollte gar keine Probleme haben – bis er von Entity Framework 4 auf 5 migriert. Wer sich eine neue Anwendung erstellen will, für den hat Microsoft die – nennen wir es neutral – Überraschungen … sofort im Gepäck, gibt dafür aber auch entsprechende Hinweise.

Neue Anwendung erstellen

Will man eine neue ASP.NET Dynamic Data Anwendung erstellen ist der Weg recht einfach über die Projekt-Templates:

image_thumb91[1]

Anschließend muss man lediglich ein zweites Assembly mit dem Datenmodell erstellen, die entsprechenden Referenzen im Web-Projekt setzen, und das Datenmodell in der global.asax korrekt anmelden… – lediglich!

Dabei gibt es jedoch ein paar Stolpersteine zu überwinden…

Erste Stolperstein: Das aktuelle Entity Framework 5 kommt nicht mit dem “normalen” .NET Framework.

Fügt man dem Assembly für das Datenmodell ein “ADO.NET Entity Data Model” hinzu, so funktioniert das ganz problemlos, einschließlich des Zufügens der notwendige Assembly-Referenzen.

Versuch man nun, eine Projekt-Referenz von seine Web-Anwendung auf das Datenmodell-Assembly zu setzen, so benötigt man dort natürlich ebenfalls eine Referenz auf das Entity-Framework, genauer EntityFramework.dll. Und obwohl das Projekt-Template genau dafür gedacht war, ist diese Referenz noch nicht gesetzt.

Der Stolperstein dabei: Die Referenz wird nicht über das üblich “Add Reference” zugefügt, sondern über NuGet (Menü: “Project” / “Manage NuGet Packages…”):

image

image

Wer mit NuGet noch nicht viel zu tun hatte, wird hier zunächst etwas verloren im “Add References” herumsuchen.

 

Zweiter Stolperstein: Der Kommentar in der global.asax führt einen erst einmal auf’s Glatteis.

   1: public static void RegisterRoutes(RouteCollection routes)

   2: {

   3:     //                    IMPORTANT: DATA MODEL REGISTRATION 

   4:     // Uncomment this line to register an ADO.NET Entity Framework model for ASP.NET Dynamic Data.

   5:     // Set ScaffoldAllTables = true only if you are sure that you want all tables in the

   6:     // data model to support a scaffold (i.e. templates) view. To control scaffolding for

   7:     // individual tables, create a partial class for the table and apply the

   8:     // [ScaffoldTable(true)] attribute to the partial class.

   9:     // Note: Make sure that you change "YourDataContextType" to the name of the data context

  10:     // class in your application.

  11:     // See http://go.microsoft.com/fwlink/?LinkId=257395 for more information on how to add and configure an Entity Data model to this project

  12:     //DefaultModel.RegisterContext(typeof(YourDataContextType), new ContextConfiguration() { ScaffoldAllTables = false });

  13:  

Wer nun brav dem Kommentar folgt und die letzte Zeile entsprechend durch den Verweis auf sein Datenmodell ersetzt…

   1: DefaultModel.RegisterContext(

   2:     typeof(ClassLibrary1.PrivatbilanzEntities), 

   3:     new ContextConfiguration() { ScaffoldAllTables = false }

   4:     );

… wird prompt mit der typischen ASP.NET-Fehlerseite begrüßt:

image

Der Grund ist, dass Microsoft mit Entity Framework 5.0 die Basisklasse der Datenkontext-Klasse geändert hat… – und ASP.NET Dynamic Data kann damit nichts anfangen.

Das Problem löst sich, wenn man dem Kommentar in der global.asax bis zur letzten Anweisung folgt, und den angegebenen Link öffnet. Über diesen wird man auf einen Blog-Beitrag verwiesen, der die Lösung beschreibt:

image

Folgt man dieser Anweisung…

   1: DefaultModel.RegisterContext(

   2:     () => ((IObjectContextAdapter)new ClassLibrary1.PrivatbilanzEntities()).ObjectContext,

   3:     new ContextConfiguration() { ScaffoldAllTables = true }

   4:     );

…, dann läuft die Anwendung zumindest bis zum nächsten Stolperstein.

 

Der letzte Stolperstein: Wo ist der Connection-String?

LINQ 2 SQL hat einen Standard-Wert für den Connection-String im generierten Code untergebracht, Entity Framework hat das nicht. Man muss als den entsprechenden Eintrag aus der app.config im Datenmodell-Assembly in die web.config kopieren.

 

Und jetzt läuft alles ohne Probleme:

image

image

 

Entity Framework 5?

Wer eine bestehende Anwendung hat oder den beschriebene Weg im Visual Studio 2010 durchführt wird noch Entity Framework 4 im Einsatz haben und daher nicht in die genannten Probleme der geänderten Basisklasse des Datenkontextes laufen. Man kann natürlich auch gezielt diesen Zustand wieder herstellen, wenn man mit Visual Studio 2012 arbeitet:

  • Assembly-Referenz auf EntityFramework.dll entfernen
  • T4-Templates samt generiertem Code aus dem Projekt entfernen:

image

  • Code-Generierung auf “Default” umstellen:

image

Aber das nur der Vollständigkeit bzw. der Erklärung halber, der Normalfall dürfte der umgekehrte Weg sein. Wer also seine bestehende Anwendung vom Entity Framework 4 auf 5 migriert wird in ASP.NET Dynamic Data-Anwendungen genau in die beschriebenen Probleme laufen. Allerdings womöglich verbunden mit der Schwierigkeit, dass der Kommentar – wenn er überhaupt noch existiert – nicht den Hinweis auf den besagten Blogbeitrag enthält.

 

Fazit

Das ist alles kein Beinbruch oder gar ein unlösbares Problem – zumindest wenn man weiß, wo man im Zweifelsfalle hinschauen muss. Dummerweise sind Projekt-Templates gerade in Fällen wichtig, in denen man gerade das nicht weiß und einen Kick-Start braucht.

Ich bin aber durchaus der Meinung, dass man die durch die geänderte Strategie im Entity Framework entstandene Inkompatibilität innerhalb von ASP.NET Dynamic Data auch dort – in der Bibliothek oder dem Projekt-Template – hätte abfangen können. Das hinterlässt den Eindruck, dass hier einige Teilteams innerhalb von Microsoft nicht sauber koordiniert gearbeitet haben.