Galileo Computing < openbook > Galileo 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

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 39 Entitätsaktualisierung und Zustandsverwaltung
Pfeil 39.1 Aktualisieren von Entitäten
Pfeil 39.1.1 Entitäten ändern
Pfeil 39.1.2 Hinzufügen neuer Entitäten
Pfeil 39.1.3 Löschen einer Entität
Pfeil 39.2 Der Lebenszyklus einer Entität im Objektkontext
Pfeil 39.2.1 Der Zustand einer Entität
Pfeil 39.2.2 Das Team der Objekte im Überblick
Pfeil 39.2.3 Neue Entitäten im Objektkontext
Pfeil 39.2.4 Die Zustände einer Entität
Pfeil 39.2.5 Zusätzliche Entitäten in den Datencache laden
Pfeil 39.2.6 Die Zustandsverfolgung mit »MergeOption« steuern
Pfeil 39.3 Das »ObjectStateEntry«-Objekt
Pfeil 39.3.1 Die Current- und Originalwerte abrufen
Pfeil 39.3.2 Die Methode »TryGetObjectStateEntry«
Pfeil 39.3.3 Abrufen bestimmter Gruppen
Pfeil 39.3.4 Die Methode »GetModifiedProperties«
Pfeil 39.4 Die Klasse »EntityKey«
Pfeil 39.4.1 Die Methoden »GetObjectByKey« und »TryGetObjectByKey«
Pfeil 39.5 Komplexere Szenarien
Pfeil 39.5.1 Die Methode »ChangeState«
Pfeil 39.5.2 Die Methoden »ApplyCurrentChanges« und »ApplyOriginalChanges«

Galileo Computing - Zum Seitenanfang

39.5 Komplexere SzenarienZur nächsten Überschrift

Entitäten, die vom Objektkontext verwaltet werden, werden per Vorgabe zustandsüberwacht durch Schaltung eines korrespondierenden ObjectStateObject-Objekts. Wir haben uns diesem Thema in diesem Kapitel ausgiebig gewidmet. Allerdings waren die Szenarien sehr einfach, denn sie beschrieben im Grunde genommen nur Clientanwendungen, aus denen heraus direkt mit Hilfe des Entity Frameworks auf die Datenquelle zugegriffen wurde.

Interessanter wird es, wenn die Entitäten über Prozessgrenzen hinweg ausgetauscht werden müssen. Das wäre zum Beispiel in n-Tier-Anwendungen wie dem Webdienst der Fall, der die Clients mit Entitäten versorgt und bei dem die Clients die Entitäten bearbeiten und danach speichern können. Wie Sie wissen, muss dem Zustand der Entitäten beim Austausch über Prozessgrenzen hinweg besondere Aufmerksamkeit geschenkt werden. Wechselt nämlich eine Entität von einem Objektkontext zu einem anderen (und das wäre zum Aktualisieren in einer Webdienstanwendung ausgehend vom Client in Richtung des Webdienstes der Fall), dann muss die vom Client übermittelte Entität dem Objektkontext des Webdienstes mit der Methode Attach hinzugefügt werden. Schlecht ist, dass dabei der Zustand der Entität auf Unchanged wechselt, obwohl sie möglicherweise tatsächlich verändert worden ist.

Sehen wir uns daher abschließend in diesem Kapitel noch an, welche Möglichkeiten der Zustandsbeeinflussung wir auf eine Entität ausüben können und welche Konsequenzen das hat.


Galileo Computing - Zum Seitenanfang

39.5.1 Die Methode »ChangeState«Zur nächsten ÜberschriftZur vorigen Überschrift

Mit der Methode ChangeState, die auf ein ObjectStateEntry-Objekt aufgerufen wird, können Sie den Zustand einer Entität auf Added, Deleted, Modified oder Unchanged festlegen. Im folgenden Codefragment wird zum Beispiel der Zustand einer Entität auf Added gesetzt.

using (NorthwindEntities context = new NorthwindEntities())
{
var prod = context.Products.First();
ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(prod);
ose.ChangeState(EntityState.Added);
[...]
}

Man muss sich natürlich darüber bewusst sein, dass die manuelle Zustandsänderung Folgen hat. In diesem Fall weist die Entität danach keine Originalwerte mehr auf. Wird SaveChanges anschließend aufgerufen, wird die Entität in die Datenbank geschrieben, weil der Zustand von Unchanged abweicht. Im schlimmsten Fall hätten Sie dann dasselbe Produkt zweimal in der Tabelle Products.

Ändern Sie den Zustand einer unveränderten Entität in Modified, hätte das nicht so gravierende Auswirkungen. Allerdings wird nun jede Eigenschaft der Entität als Modified gekennzeichnet, was zu einem UPDATE-Statement führt, in dem alle Eigenschaften aufgeführt sind. Nur eine Änderung in den Zustand Deleted hat keine negativen Konsequenzen, da der Effekt derselbe ist wie beim Aufruf der Methode DeleteObject.

Unsere Betrachtungen bezogen sich bis hierher auf ursprünglich unveränderte Entitäten. Bei der manuellen Zustandsänderung mit ChangeState ist noch eine weitere Situation zu betrachten. Diese stellt sich ein, wenn der Zustand einer Entität Modified ist und dann auf Unchanged gesetzt wird. In diesem Fall werden alle Current-Werte in die korrespondierenden Originalwerte geschrieben – obwohl man im ersten Moment vermuten würde, der Vorgang müsste sich genau andersherum abspielen.

Summa summarum sollten Sie also die Methode ChangeState nur mit Bedacht aufrufen und sich immer der möglichen Folgen bewusst sein.


Galileo Computing - Zum Seitenanfang

39.5.2 Die Methoden »ApplyCurrentChanges« und »ApplyOriginalChanges«Zur vorigen Überschrift

Ein Entitätsobjekt ist fest mit seinem Objektkontext verbunden. Darüber hinaus darf eine Entität auch nur zu einem Objektkontext gehören. Das führt dazu, dass der folgende Code zu einer Ausnahme führt, weil versucht wird, die Entität über den Methodenaufruf von DoSomething einem anderen Objektkontext, hier context2, zu übergeben.

static void Main(string[] args)
{
using (NorthwindEntities context1 = new NorthwindEntities())
{
var prod = context1.Products.First();
prod.ProductName = "Currywurst";
DoSomething(prod);
}
}

static void DoSomething(Product product)
{
using (NorthwindEntities context2 = new NorthwindEntities())
{
context2.Attach(product);
}
}

Es gibt nur eine Möglichkeit, diesen Fehler zu vermeiden, indem man vor dem Aufruf der Methode DoSomething in Main die Entität mit Detach beim ersten Objektkontext deregistriert. Damit lautet der Code in Main wie folgt:

using (NorthwindEntities context1 = new NorthwindEntities())
{
var prod = context1.Products.First();
prod.ProductName = "Currywurst";
context1.Detach(prod);
DoSomething(prod);
}

Widmen wir unser Augenmerk nun dem Code in der Methode DoSomething. Da wir die Entität mit Attach dem Objektkontext context2 hinzufügen, wird der Zustand der Current- und Original-Werte anschließend identisch sein. Dabei geht aber nicht die Änderung der Eigenschaft ProductName verloren. Stattdessen wird der neue Wert (»Currywurst«) an OriginalValue übergeben, wie sich sehr einfach durch Ergänzung der Methode DoSomething beweisen lässt.

static void DoSomething(Product prod)
{
using (NorthwindEntities context2 = new NorthwindEntities())
{
context2.Attach(prod);
ObjectStateEntry ose = context2.ObjectStateManager.GetObjectStateEntry(prod);
Console.WriteLine("Current: {0}", ose.CurrentValues.GetValue(1));
Console.WriteLine("Original: {0}\n", ose.OriginalValues.GetValue(1));
}
}

Mit dieser Erkenntnis müssen wir feststellen, in einem Dilemma zu stecken. Soll nämlich DoSomething dazu dienen, die Entitätsänderung durch Aufruf der Methode SaveChanges in die Datenbank zu schreiben, wird kein UPDATE-Statement erzeugt, weil der Zustand Unchanged lautet.

In dieser Situation hilft uns die Methode ApplyOriginalValues weiter, die entweder auf den Objektkontext oder ein EntitySet aufgerufen werden kann. Sie können die Methode dann benutzen, wenn die zustandsverfolgte Entität zwar die richtigen Current-Werte aufweist, aber die Originalwerte nicht stimmen. Das ist in unserem Beispiel genau der Fall. Sehen wir uns zunächst an, wie die Methode DoSomething implementiert werden muss.

using (NorthwindEntities context2 = new NorthwindEntities())

{

// Original-Entität aus der Datenbank abrufen

var dbprod = context2.Products
.Where(p => p.ProductID == prod.ProductID).Single();
context2.Detach(dbprod);

// Entität zum Objektkontext hinzufügen

context2.Attach(prod);
Console.WriteLine("Zustand (vorher): {0}", prod.EntityState);

// Originalwerte neu festlegen

context2.Products.ApplyOriginalValues(dbprod);

// Ausgabe

ObjectStateEntry ose = context2.ObjectStateManager.GetObjectStateEntry(prod);
Console.WriteLine("Zustand (nachher): {0}", prod.EntityState);
Console.WriteLine("Current: {0}", ose.CurrentValues.GetValue(1));
Console.WriteLine("Original: {0}\n", ose.OriginalValues.GetValue(1));
}

ApplyOriginalChanges benötigt die aktuellen Werte für die übergebene Entität. Dazu wird der Methode ein anderes Objekt übergeben, das die erforderlichen Werte enthält. Dieses Objekt wird als Erstes in der Methode DoSomething von der Datenbank abgerufen.

In einem Objektkontext kann sich zu einem gegebenen Zeitpunkt immer nur ein Objekt mit einer bestimmten Schlüsselinformation befinden. Da wir wissen, dass wir auch die geänderte Entität zur Zustandsverwaltung hinzufügen müssen, wird die von der Datenbank bezogene Entität dbprod beim Objektkontext deregistriert. Dass sich dabei der Zustand in Detached ändert und alle Originalwerte verloren gehen, hat keinen Einfluss. Letztendlich sind die erforderlichen Informationen immer noch unter CurrentValues vorhanden.

Nach dem Aufruf von ApplyOriginalValues hat die Entität alle benötigten Originalwerte, und der Zustand hat sich in Modified geändert. Damit wäre das Objekt so weit vorbereitet, die Änderung am ProductName erfolgreich in die Datenbank zu schreiben.

Sehr ähnlich arbeitet auch die Methode ApplyCurrentValues. Während ApplyOriginalValues aber die Daten eines Objekts an die Originalwerte einer Entität übergibt, sind es mit ApplyCurrentValues die Current-Werte der Entität.

Den Programmcode zu diesem Beispiel finden Sie auf der Buch-DVD unter \Beispiele\Kapitel 39\SeveralObjectContexts.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2012

Visual C# 2012
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
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.


[Rheinwerk Computing]

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