Der normale Weg für ein Datenbankdesign, zumindest der, den viele Entwickler gehen, ist für eine Tabelle einen Primärschlüssel (PK) zu setzen. Dabei ist der Datentyp der “Id” Spalte meistens ein Integer (int). Dieser wird dann, meistens automatisch von der Datenbank, inkrementiert, damit er eindeutig bleibt. Doch im Zeitalter von mobilen Anwendungen ist es sinnvoller einen Datentyp zu verwenden, der nicht nur lokal bei einer Datenbank eindeutig ist, sondern auch über Datenbanken und Netze hinweg, z.B. auf dem Mobiltelefon oder einer anderen Datenbank. Für diesen Fall ist beim Microsoft SQL Server 2005/2008 der uniqueidentifier vorgesehen. Unter .NET kennt man diesen Datentypen auch als Guid. Dieser Datentyp hat den Vorteil, dass er immer eindeutig bleibt.

Dieser Weg blieb mit dem Entity Framework bislang verwehrt, wollte man die GUIDs vom Server generieren lassen. Es ist jetzt jedoch sehr wohl möglich, seit Version 4 des Entity Frameworks werden servergenerierte GUID-Typidentitätswerte unterstützt. Alle anderen Aussagen in Blogs und Forenbeiträgen unserer Internationalen Entwicklerkollegen diesbezüglich, die ich finden konnte, verweisen leider fälschlicher Weise auf eine veraltete MSDN Seite für Version 1 des EF.

Auf der aktuellen und handübersetzen MSDN Seite wird es jedoch explizit benannt, trotzdem fehlt es an einer genauen Beschreibung, wie man vorgehen muss.

 

Da ich selbst immer wieder auf Hindernisse gestoßen bin, dieses Konzept mit dem Entity Framework zu benutzen, jetzt ein klare, direkte Anleitung, wie es garantiert funktioniert.

Durchgeführt mit dem Visual Studio 2010 RTM + Silverlight 4 Tools RC2, SQLServer 2008. Funktionierenden Einsatz findet die Technik in einer Silverlight 4 Business Anwendung mit RIA Services

Am SQL-Server 2008:

  1. Tabelle mit einer Spalte, z.B. “Id”, vom Datentyp uniqueidentifier erstellen.
  2. Defaultwert der Spalte auf newid() setzen.
  3. “Id” Spalte als Primary Key setzen.

In Visual Studio 2010:

  1. Datenbank-Model für EF erzeugen.
  2. T4 Templates erstellen mit Rechtsklick ins Design “Add Codegeneration Item”.
  3. Tabellen-Entity auswählen und StoreGeneratedPattern beim Id-Property auf Identity stellen.
  4. Speichern.

Unter besten Bedingungen sollte es jetzt klappen. Leider nicht bei mir, und bei vielen anderen auch nicht. Den eigentlichen Fehler zu finden hat mich sehr viel Zeit gekostet. Er liegt im Entity Framework Designer. Es handelt sich um einen Bug beim setzen der Entityproperty-Eigenschaft StoreGeneratedPattern. Nähere Infos zum Bug sowie ein netten Kommentar eines Linq-To-Sql Fans über EF sowie der Namensgabe der Eigenschaft findet man hier.
Um den Bug zu fixen fehlt noch der wichtigste Schritt:


Der wichtigste Schritt:

  1. Den EF-Designer schließen und die edmx-Datei mit dem XML-Editor öffnen (Rechtsklick auf die Datei –> “Open with..”)
  2. Im StorageModel kontrollieren und wahrscheinlich nachtragen:

<EntityType Name="TestTabelle">
          <Key>
            <PropertyRef Name="Id" />
          </Key>
          <Property Name="Id" Type="uniqueidentifier" Nullable="false" StoreGeneratedPattern="Identity"/>
          <Property Name="Test" Type="varchar" MaxLength="50" />
</EntityType>

Jetzt sollte alles bestens funktionieren. Das selbe Prinzip ist auch bei Spalten wie z.B. “DateCreated” mit einem datetime Datentyp und einer getdate() Methode anwendbar. Einfach StoreGeneratedPattern = Identity setzen und im StorageModel, wenn nicht vorhanden, so wie oben nachtragen.

Bitte beachten, das bei Updates vom Designer diese Werte überschrieben werden können.

 

Der Vollständigkeit halber, einige Fehlermeldungen, mit denen ich in diesem Zusammenhang zutun hatte, damit Leute mit ähnlichen Problem diesen Beitrag schneller finden können:

[System.Data.SqlClient.SqlException] = {"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated."}


 
Saturday, April 24, 2010 9:03:57 AM (W. Europe Standard Time, UTC+01:00)
We noch mehr customizen will, kann natürlich auch das T4 Template ändern. Die kostenlose Edition des tangible T4 Editors unter http://t4-editor.tangible-engineering.com ist dabei eine große Hilfe, da man so intelliSense und Syntax-Coloring bekommt.
Wednesday, December 22, 2010 1:28:25 PM (W. Europe Standard Time, UTC+01:00)
danke für den Hinweis, ich hab mir schon einen Wolf gesucht.
Unter
http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/
gibt's weitere Details und Kommentare.
Unterm Strich bleibt ein unzureichendes Verhalten des EF, deshalb löse ich das Problem in der Datenbank per InsertTrigger. Wenn die vom EF erzeugte GUID unbrauchbar ist, wird hier einfach eine neue erzeugt und gut ist.
der den Wolf sucht
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview