Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 37 Einführung in das ADO.NET Entity Framework
Pfeil 37.1 Kritische Betrachtung von ADO.NET
Pfeil 37.2 Ein erstes Entity Data Model (EDM) erstellen
Pfeil 37.3 Das Entity Data Model im Designer
Pfeil 37.3.1 Die übergeordneten Eigenschaften einer Entität
Pfeil 37.3.2 Eigenschaften eines Entitätsobjekts
Pfeil 37.3.3 Assoziationen im Entity Data Model
Pfeil 37.3.4 Der Kontext der Entitäten
Pfeil 37.4 Der Aufbau des Entity Data Models
Pfeil 37.5 Die Klassen des Entity Data Models (EDM)
Pfeil 37.5.1 Die Entitätsklassen
Pfeil 37.5.2 Der ObjectContext
Pfeil 37.6 Die Architektur des Entity Frameworks
Pfeil 37.6.1 Object Services
Pfeil 37.6.2 Die Schichten des Entity Frameworks

Rheinwerk Computing - Zum Seitenanfang

37.5 Die Klassen des Entity Data Models (EDM)Zur nächsten Überschrift

Wenn Sie mit dem Assistenten ein Entity Data Model bereitstellen, wird neben der EDMX-Datei auch noch eine weitere Datei mit der Dateierweiterung designer.cs erzeugt. In dieser Datei sind die Klassen enthalten, die die konzeptionelle Schicht in die Programmiersprache Ihrer Wahl umsetzen. Mit von der Partie sind die Klassen, die die Entitäten des Entity Data Models beschreiben. Bezogen auf das von uns erstellte EDM handelt es sich um die Klassen Product und Category. Außerdem wird in der Codedatei noch eine Klasse namens NorthwindEntities beschrieben. Diese stellt die Umgebung bereit, innerhalb deren die Entitätsdaten abgefragt und bearbeitet werden können.


Rheinwerk Computing - Zum Seitenanfang

37.5.1 Die EntitätsklassenZur nächsten ÜberschriftZur vorigen Überschrift

Im Entity Framework arbeiten Sie nicht direkt mit Datensätzen. Stattdessen werden die von der Datenbank bezogenen Daten eines Datensatzes in einem Entitätsobjekt materialisiert. Die entsprechende Entitätsklasse mit allen erforderlichen Membern beschreibt das Entity Data Model in der Datei mit der Extension designer.cs. Wir wollen uns nun die Entität Product ansehen, die die Tabelle Products der Northwind-Datenbank abbildet. Dabei sei auch in diesem Beispiel davon ausgegangen, dass im EDM neben der Entität auch die Entität Category beschrieben wird. Jede Entitätsklasse wird von der Basis EntityObject abgeleitet:

[EdmEntityType(NamespaceName="NorthwindModel", Name="Product")]
[Serializable()]
[DataContract(IsReference=true)]
public partial class Product : EntityObject

Damit hat eine Entität von Anfang an eine gewisse Basisfunktionalität. Da ein Objekt vom Typ einer Entität häufig auch die Prozessgrenzen verlassen muss (beispielsweise bei einer Webanwendung), ist die Serialisierbarkeit sehr wichtig. Aus diesem Grund ist jede Entitätsklasse mit den Attributen Serializable und DataContract verknüpft.

Zu den von der Basis EntityObject geerbten Membern gehören die beiden Eigenschaften EntityState und EntityKey. Beide spielen im Zusammenhang mit der Zustandsverfolgung und der Aktualisierung einer Entität eine wichtige Rolle. Darüber hinaus erbt eine Entität auch die beiden Ereignisse PropertyChanging und PropertyChanged, die über die Methoden OnPropertyChanging und OnPropertyChanged ausgelöst werden können.

Der Code einer Entität

Jede Entität, die auch gleichzeitig in Beziehung zu einer anderen im Entity Data Model steht, wird durch drei Methodengruppen beschrieben:

  • eine Factory-Methode
  • primitive Eigenschaften
  • Navigationsmethoden

Betrachten wir zuerst die Factory-Methode ganz am Anfang der Entitätsklasse.

// Factory-Methode
public static Product CreateProduct(Int32 productID, String productName,
Boolean discontinued)
{
Product product = new Product();
product.ProductID = productID;
product.ProductName = productName;
product.Discontinued = discontinued;
return product;
}

Grundsätzlich können Sie natürlich eine neue Entität durch den Aufruf des Konstruktors erzeugen. Das ist beispielsweise dann von Interesse, wenn Sie die neue Entität in die Datenbank als neuen Datensatz zurückschreiben wollen. Da es aber keinen parametrisierten Konstruktor gibt, bleibt Ihnen nichts anderes übrig, als allen Feldern, die nicht null sein dürfen, ausdrücklich einen Wert zu übergeben. Die Factory-Methode in der Entitätsklasse unterstützt Sie dabei in der Weise, dass für jedes nicht-null-fähige Feld ein Parameter definiert ist, dem Sie beim Methodenaufruf ein Argument übergeben müssen.

Jede Spalte in der Datenbank wird in der Entitätsklasse durch eine Eigenschaft abgebildet, die den zugehörigen Wert in einem privaten Feld speichert. Exemplarisch sei an dieser Stelle die Eigenschaft ProductName der Entität Product gezeigt.

// Primitive Eigenschaften
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public String ProductName

{
get { return _ProductName; }
set
{
OnProductNameChanging(value);
ReportPropertyChanging("ProductName");
_ProductName = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("ProductName");
OnProductNameChanged();
}
}
private String _ProductName;
partial void OnProductNameChanging(String value);
partial void OnProductNameChanged();

Entitätseigenschaften sind mit den Attributen EdmScalarProperty und DataMember verknüpft. Mit dem DataMember-Attribut werden Eigenschaften gekennzeichnet, die beim Aufruf eines Services (z. B. beim Einsatz innerhalb der WCF – Windows Communication Foundation) serialisiert werden müssen. Interessanter ist momentan das Attribut EdmScalarProperty. Dessen Eigenschaft EntityKeyProperty gibt an, ob die mit diesem Attribut verknüpfte Entitätseigenschaft Teil des Entitätsschlüssels (der in der Regel dem Primärschlüssel entspricht) ist. Wie wir wissen, trifft das nicht auf ProductName zu. Die IsNullable-Eigenschaft wiederum gibt an, ob die Entitätseigenschaft den Wert null aufweisen kann. Das trifft auf ProductName nicht zu.

Über den get-Zweig der Eigenschaft muss eigentlich kein weiteres Wort verloren werden. Er liefert ausschließlich den Wert der Eigenschaft zurück. Etwas aufwendiger ist da schon der set-Zweig implementiert. Inmitten der insgesamt fünf Anweisungen finden wir die Zuweisung des Wertes an das private Feld _ProductName. Davor wird das Ereignis ReportPropertyChanging ausgelöst und die partielle Methode OnProductNameChanging aufgerufen. Ähnliches spielt sich auch nach der Wertzuweisung ab: die Auslösung des Ereignisses ReportPropertyChanged und der Aufruf einer partiellen Methode OnProductNameChanged.

Wir sollten zuerst über die beiden Ereignisse sprechen. Die Entitätsklasse kann natürlich von mehreren Methoden in der Anwendung genutzt werden. Es ist durchaus vorstellbar, dass im Zusammenhang mit der Zuweisung an die Eigenschaft ProductName innerhalb der Methoden unterschiedliche Reaktionen verbunden werden sollen. Vielleicht soll beim Aufruf einer Methode vor der Eigenschaftswertänderung die Aktion in ein Protokoll geschrieben werden, während eine andere Methode nur eine Information an den Anwender sendet. In solchen Fällen, in denen es zu unterschiedlichen Reaktionen kommen soll, bieten sich Ereignisse an – in unserem Fall speziell die Events ReportPropertyChanging und ReportPropertyChanged.

Einen anderen Zweck verfolgt die Bereitstellung der beiden partiellen Methoden OnProductNameChanging und OnProductNameChanged. Diese dienen dazu, Code bereitzustellen, der immer dann ausgeführt wird, wenn sich die Eigenschaft ändert. Im ersten Moment scheint nichts dagegen zu sprechen, den gewünschten Code direkt in den set-Zweig der Eigenschaft zu schreiben. Es gibt aber dennoch ein Gegenargument: Wird das Entity Data Model aus der Datenbank aktualisiert, geht der zusätzliche benutzerdefinierte Code verloren. Er wird schlicht und ergreifend »aktualisiert«. Diese unerwünschte »Aktualisierung« wird mit partiellen Methoden vermieden. Partielle Methoden werden in einer partiellen Teildefinition der Klasse implementiert. Bei einer gewollten Aktualisierung des Entity Data Models bleibt der partielle Teil mit der Implementierung der partiellen Methoden davon unbetroffen.

Zum Schluss unserer Betrachtungen sollen auch die Navigationsmethoden noch erwähnt werden. In der Entität Product lauten sie Category und CategoryReference. Der Einfachheit halber sei an dieser Stelle nur die Struktur wiedergegeben:

public Category Category
{
[...]
}
public EntityReference<Category> CategoryReference
{
[...]
}

Die Navigationsmethoden dienen dazu, eine bestehende Beziehung zu nutzen, um von einer Entität zu einer in Beziehung stehenden Entität zu navigieren. In den beiden folgenden Kapiteln werden Sie den Einsatz der Navigationsmethoden erfahren.


Rheinwerk Computing - Zum Seitenanfang

37.5.2 Der ObjectContextZur vorigen Überschrift

Neben den im Abschnitt zuvor beschriebenen Entitäten ist der Objektkontext das zentrale Element des Entity Frameworks. Der Objektkontext wird durch ein Objekt beschrieben, das von der Basis ObjectContext abgeleitet ist. Ohne den Objektkontext, der gleichzeitig auch der Cache für die Entitätsobjekte ist, können Sie keine Abfragen ausführen oder Objektänderungen speichern. Darüber hinaus überwacht der Objektkontext die Änderungen an den Entitätsobjekten und berücksichtigt dabei auch die Einhaltung der im EDM enthaltenen Assoziationen.

Sehen wir uns nun die elementare Struktur der Klassendefinition des Objektkontextes in unserem EDM an (Abbildung 37.12).

Abbildung

Abbildung 37.12 Die Klassendefinition des ObjectContexts

Der Objektkontext definiert mehrere Konstruktoren.

public NorthwindEntities() : base("name=NorthwindEntities", 
"NorthwindEntities")

{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
public NorthwindEntities(string connectionString) : base(connectionString,
"NorthwindEntities")

{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
public NorthwindEntities(EntityConnection connection) : base(connection,
"NorthwindEntities")

{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}

Der parameterlose Konstruktor verwendet die in der Konfigurationsdatei (app.config) hinterlegte Verbindungszeichenfolge zum Aufbau der Verbindung zur Datenbank. Darüber hinaus haben Sie die Möglichkeit, eine Verbindungszeichenfolge explizit anzugeben oder ein EntityConnection-Objekt zu übergeben.

In den Konstruktoren wird die Methode OnContextCreated aufgerufen. Hierbei handelt es sich um eine partielle Methode, die es Ihnen ermöglicht, bei der Instanziierung der ObjectContext-Klasse eigenen Code hinzuzufügen.

Für jede im Entity Data Model beschriebene Entität wird durch den Objektkontext eine schreibgeschützte Eigenschaft bereitgestellt, die die Menge aller Objekte des entsprechenden Entitätstyps beschreibt. In unserem EDM-Beispiel handelt es sich um die Eigenschaften Products und Categories. Der Rückgabewert ist jeweils vom Typ ObjectSet<T>.

private ObjectSet<Category> _Categories;
private ObjectSet<Product> _Products;
public ObjectSet<Category> Categories {
get {
if ((_Categories == null)) {
_Categories = base.CreateObjectSet<Category>("Categories");
}
return _Categories;
}
}
public ObjectSet<Product> Products {
get {
if ((_Products == null)) {
_Products = base.CreateObjectSet<Product>("Products");
}
return _Products;
}
}

Wenn wir im nächsten Kapitel unsere LINQ-Abfragen codieren, ist die Menge der Entitäten immer Ausgangspunkt aller weiteren Überlegungen.



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.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual C# 2012

Visual C# 2012
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: C/C++






 C/C++


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern