37.4 Der Aufbau des Entity Data Models![Zur nächsten Überschrift](common/down.gif)
Das Entity Data Model können Sie sich auch als Bindeglied zwischen der Datenbank und Ihrem Programmcode vorstellen. Nachdem wir uns im letzten Abschnitt den visualisierten Teil des EDM angesehen haben, wollen wir nun ein wenig hinter die Kulissen sehen, um die Zusammenhänge besser zu verstehen.
Da ein Doppelklick auf die EDMX-Datei nur dazu führt, dass die Designansicht geöffnet wird, wollen wir diese Datei nun auf andere Weise öffnen. Dazu markieren Sie die EDMX-Datei im Projektmappen-Explorer und öffnen mit der rechten Maustaste das Kontextmenü. Wählen Sie hier Öffnen mit ... Aus der Ihnen angebotenen Liste von Tools sollten Sie die Option XML Editor auswählen. Sollte in diesem Moment die EDMX-Datei in der Designansicht noch geöffnet sein, werden Sie noch darauf hingewiesen und gefragt, ob die geöffnete Datei geschlossen werden soll. Sie können das bestätigen. In Visual Studio werden Ihnen daraufhin gewissermaßen die »Rohdaten« des Entity Data Models im XML-Format angezeigt.
Im ersten Moment hinterlässt die Datei einen verwirrenden Eindruck. Aber bei genauer Betrachtung gliedert sich die Datei in zwei Hauptabschnitte: ein Abschnitt Runtime, der Laufzeitinformationen enthält, und ein Abschnitt Designer, der Informationen für die Darstellung in der Design-Ansicht enthält. Der Abschnitt Runtime seinerseits beschreibt drei untergeordnete Abschnitte:
- CSDL (Conceptual Schema Definition Language): Dieser Abschnitt beherbergt das konzeptionelle Modell und beschreibt somit die Schicht, gegen die Sie Ihren Programmcode schreiben.
- SSDL (Storage Schema Definition Language): Diese Schicht beschreibt das Schema der Datenbank.
- MSL (Mapping Specification Language): Diese Schicht bildet das konzeptionelle Modell (CSDL) auf das Schema der Datenbank (SSDL) ab.
In Abbildung 37.10 sind die Hauptabschnitte im zusammengeklappten Zustand dargestellt.
Abbildung 37.10 XML-Struktur des Entity Data Models (EDM)
Der Abschnitt SSDL (Store Schema Definition Language)
Dieser Abschnitt, der häufig auch als physikalisches Modell oder Speichermodell bezeichnet wird, bildet die Daten der Datenquelle durch XML ab. Diese Sektion wird durch das <Schema>-Element beschrieben, das mit <EntityContainer>, <EntityType> und <Association> weiter aufgegliedert wird.
Neben dem Namespace-Attribut werden im <Schema>-Element auch die Attribute Provider und ProviderManifestToken angeführt. Die letztgenannten Attribute geben an, über welchen Provider die Verbindung zur Datenbank aufgenommen wird, sowie deren Version.
Das <EntityContainer>-Element beschreibt die Struktur der zugrunde liegenden Datenquelle und gliedert sich selbst in die beiden untergeordneten Elemente <EntitySet> und <AssociationSet>. EntitySet stellt eine Tabelle der Datenbank dar, AssociationSet die Beziehung zwischen den Tabellen des aktuellen Entity Data Models. Sehen wir uns zunächst den Abschnitt an, der die Tabelle Categories beschreibt.
<EntityType Name="Categories">
<Key>
<PropertyRef Name="CategoryID" />
</Key>
<Property Name="CategoryID" Type="int" Nullable="false"
StoreGeneratedPattern="Identity" />
<Property Name="CategoryName" Type="nvarchar" Nullable="false"
MaxLength="15" />
<Property Name="Description" Type="ntext" />
<Property Name="Picture" Type="image" />
</EntityType>
Wir können erkennen, dass jede Spalte der Tabelle hinsichtlich des Namens, des Datentyps und ihrer Einschränkungen durch Attribute des <Property>-Elements angegeben ist. Bei den Datentypangaben handelt es sich um die datenbankspezifischen, in unserem Fall um die des SQL Servers. Die Primärschlüsselfelder sind durch das <Key>-Element namentlich aufgeführt.
Das <Association>-Element definiert die Beziehungen zwischen den in unserem Entity Data Model enthaltenen Tabellen.
<Association Name="FK_Products_Categories">
<End Role="Categories" Type="NorthwindModel.Store.Categories"
Multiplicity="0..1" />
<End Role="Products" Type="NorthwindModel.Store.Products"
Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Categories">
<PropertyRef Name="CategoryID" />
</Principal>
<Dependent Role="Products">
<PropertyRef Name="CategoryID" />
</Dependent>
</ReferentialConstraint>
</Association>
Eine Beziehung zwischen zwei Tabellen hat zwei Endpunkte. Diese werden, ergänzt um die Angabe der Multiplizität, zuerst angegeben. <ReferentialConstraint> definiert die Charakteristik der referenziellen Einschränkung: Die Tabelle Products ist die abhängige (engl.: dependent) Seite, also die Detailtabelle, die Tabelle Categories die Mastertabelle. In beiden Tabellen lauten die Spalten, zwischen denen die referenzielle Einschränkung definiert ist, CategoryID.
Immer dann, wenn Daten zur Datenbank gesendet werden, wird das Entity Framework mit Hilfe des Abschnitts <ReferentialConstraint> prüfen, ob gegen die referenzielle Einschränkung verstoßen wird. Sollte das der Fall sein, werden die Daten nicht gesendet.
Der Abschnitt CSDL (Conceptual Schema Definition Language)
Der Abschnitt CSDL stellt das konzeptionelle Schema dar und beschreibt die Schicht, gegen die Sie später programmieren werden. Natürlich werden Sie nicht die XML-Elemente mit dem Code ansprechen, vielmehr dient dieses Schema dem Assistenten dazu, daraus Klassen zu generieren. Diese werden wir uns weiter unten noch ansehen.
Der CSDL-Abschnitt der EDMX-Datei ähnelt sehr stark dem SSDL-Abschnitt. Er enthält ein <EntityContainer>-Element, für jede abgebildete Tabelle ein <EntityType>-Element und ein Element <Association>, um die referenziellen Einschränkungen der Tabellen zu definieren. Dennoch sind einige Unterschiede durchaus erwähnenswert. Beispielsweise bezieht sich der Datentyp in den spaltenbeschreibenden <Property>-Elementen nicht mehr auf datenbankspezifische Typen, sondern bildet die Datentypen des .NET Frameworks ab. Einen weiteren wesentlichen Unterschied stellen wir bei den Eigenschaften fest, die Zeichenfolgen beschreiben. Hier werden zusätzliche Attribute angegeben, um zum Beispiel die Länge einer Zeichenfolge festzulegen. Zu den Eigenschaften gesellt sich zudem ein Element <NavigationProperty>. Dieses beschreibt, wie zwischen den an einer Beziehung beteiligten Entitäten navigiert wird. Das folgende Codefragment zeigt den Abschnitt <EntityType> der Entität Category.
<EntityType Name="Category">
<Key>
<PropertyRef Name="CategoryID" />
</Key>
<Property Name="CategoryID" Type="Int32" Nullable="false"
annotation:StoreGeneratedPattern="Identity" />
<Property Name="CategoryName" Type="String" Nullable="false"
MaxLength="15" Unicode="true" FixedLength="false" />
<Property Name="Description" Type="String" MaxLength="Max" Unicode="true"
FixedLength="false" />
<Property Name="Picture" Type="Binary" MaxLength="Max"
FixedLength="false" />
<NavigationProperty Name="Products"
Relationship="NorthwindModel.FK_Products_Categories"
FromRole="Categories" ToRole="Products" />
</EntityType>
Der Abschnitt MSL (Mapping Specification Language)
Die beiden zuvor beschriebenen Abschnitte SSDL und CSDL müssen zueinander in Beziehung gesetzt werden. Diese Aufgabe übernimmt die dritte Schicht im Entity Data Model.
Die Mapping-Sektion der EDMX-Datei lässt sich in einem separaten Fenster visualisieren. Markieren Sie dazu in der Design-Ansicht des Entity Data Models eine Entität, und wählen Sie im Kontextmenü die Option Tabellenmapping. Die Mappinginformationen der entsprechenden Entität werden danach im Fenster Mappingdetails angezeigt (siehe Abbildung 37.11).
Abbildung 37.11 Mappingdetails der Entität »Product«
Die Abbildung zeigt, wie die Entität Product auf die Tabelle Products der SSDL abgebildet wird. Es ist zu erkennen, dass es sich um 1:1-Mapping zwischen der konzeptionellen und der Speicherschicht handelt. In der Liste Spaltenmappings sind auf der linken Seite die Spalten der Speicherschicht angegeben, auf der rechten die entsprechenden Eigenschaften im konzeptionellen Modell. Das ist daran zu erkennen, dass links Datentypen des SQL Servers angegeben sind, auf der rechten Seite die Entsprechungen im .NET Framework.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.