Hinzufügen, Ändern und Löschen von Objekten (Entity Framework)

Objekte in einem Objektkontext sind Instanzen von Entitätstypen, die Daten in der Datenquelle darstellen. Es ist möglich, Objekte in einem Objektkontext zu ändern, zu erstellen und zu löschen. Object Services verfolgt die an den Objekten durchgeführten Änderungen nach. Beim Aufrufen der SaveChanges-Methode werden von Object Services Befehle generiert und ausgeführt, die die entsprechenden Anweisungen für die Datenquelle zum Einfügen, Aktualisieren oder Löschen ausführen. Weitere Informationen finden Sie unter Speichern von Änderungen und Verwalten von Parallelität (Entity Framework).

Nehmen Sie beispielsweise an, dass Sie eine Abfrage ausführen, die ein SalesOrderHeader-Objekt und eine Auflistung verbundener SalesOrderDetail-Objekte zurückgibt. Sie können beispielsweise die Auflistung durchlaufen und die folgenden Operationen ausführen:

  • Ändern der ShipDate-Eigenschaft einer Bestellung.

  • Löschen einer bestimmten Position durch Aufrufen der DeleteObject-Methode.

  • Hinzufügen einer Position zur Bestellung durch Aufrufen der Add-Methode.

  • Rufen Sie die SaveChanges-Methode für den Objektkontext auf, um die Objektänderungen in der Datenquelle zu speichern.

Im folgenden Beispiel werden verschiedene Änderungen an Objekten in einem Objektkontext veranschaulicht:

Dim order As SalesOrderHeader = _
context.SalesOrderHeader.Where( _
        "it.SalesOrderID = @id", New ObjectParameter( _
         "id", orderId)).First()

' Change the status and ship date of an existing order.
order.Status = 1
order.ShipDate = DateAndTime.Today

' Load items for the order, if not already loaded.
If Not order.SalesOrderDetail.IsLoaded Then
    order.SalesOrderDetail.Load()
End If

' Delete the first item in the order.
context.DeleteObject(order.SalesOrderDetail.First())

' Create a new item using the static Create method
' and add it to the order.
order.SalesOrderDetail.Add( _
    SalesOrderDetail.CreateSalesOrderDetail( _
    1, 0, 2, 750, 1, CDec(2171.2942), 0, 0, Guid.NewGuid(), _
    DateAndTime.Today))

' Save changes in the object context to the database.
Dim changes As Integer = context.SaveChanges()
SalesOrderHeader order =
    context.SalesOrderHeader.Where
    ("it.SalesOrderID = @id", new ObjectParameter(
     "id", orderId)).First();

// Change the status and ship date of an existing order.
order.Status = 1;
order.ShipDate = DateTime.Today;

// Load items for the order, if not already loaded.
if (!order.SalesOrderDetail.IsLoaded)
{
    order.SalesOrderDetail.Load();
}

// Delete the first item in the order.
context.DeleteObject(order.SalesOrderDetail.First());

// Create a new item using the static Create method 
// and add it to the order.
order.SalesOrderDetail.Add(
    SalesOrderDetail.CreateSalesOrderDetail(0,
    0, 2, 750, 1, (decimal)2171.2942, 0, 0,
    Guid.NewGuid(), DateTime.Today));

// Save changes in the object context to the database.
int changes = context.SaveChanges();

Hinzufügen von Objekten

Um der Datenquelle Daten hinzuzufügen, erstellen Sie eine Instanz eines Entitätstyps und fügen das Objekt einem Objektkontext hinzu. Bevor Sie ein neues Objekt hinzufügen können, müssen alle Eigenschaften festgelegt werden, die keine null-Werte unterstützen. Es kann sinnvoll sein, die statische CreateObjectName-Methode des Entitätstyps zu verwenden, um eine neue Instanz eines Entitätstyps zu erstellen. Die Entitätsdatenmodell-Tools fügen diese Methode beim Generieren der Entitätstypen jeder Klasse hinzu. Diese Create-Methode wird zum Erstellen der Instanzen von Objekten und zum Festlegen aller Eigenschaften der Klasse, die nicht null sein dürfen, verwendet. Die Methode enthält einen Parameter für jede Eigenschaft, für die in der CSDL-Datei das Nullable="false"-Attribut festgelegt wurde.

Im folgenden Beispiel wird die statische CreateSalesOrderHeader-Methode verwendet, um eine neue Instanz der SalesOrderHeader-Klasse zu erstellen.

' Create a new SalesOrderHeader using the static 
' CreateSalesOrderHeader method.
Dim order As SalesOrderHeader = _
    SalesOrderHeader.CreateSalesOrderHeader( _
    1, Convert.ToByte(1), DateTime.Now, DateTime.Today.AddMonths(2), _
    Convert.ToByte(1), False, String.Empty, customer.ContactID, shipMethod, _
    0, 0, 0, 0, Guid.NewGuid(), DateTime.Now)
// Create a new SalesOrderHeader using the static 
// CreateSalesOrderHeader method.
SalesOrderHeader order = SalesOrderHeader.CreateSalesOrderHeader(0,
    Convert.ToByte(1), DateTime.Now, DateTime.Today.AddMonths(2),
    Convert.ToByte(1), false, string.Empty, customer.ContactID, shipMethod, 
    0, 0, 0, 0, Guid.NewGuid(), DateTime.Now);

Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines Objekts mit der statischen 'Create'-Methode (Entity Framework).

Sie können dem Objektkontext neue Objekte durch Aufrufen der AddObject-Methode hinzufügen oder durch Aufrufen einer der AddToEntitySetName-Methoden der typisierten ObjectContext. Ein Objekt kann einem Objektkontext auch dadurch hinzugefügt werden, dass Sie es einer vorhandenen EntityCollection hinzufügen. Wenn Sie die Add-Methode für eine EntityCollection aufrufen, die an einen Objektkontext angefügt ist, wird das Objekt dem gleichen ObjectContexthinzugefügt. Auf ähnliche Weise können Sie ein Objekt hinzufügen, indem Sie die neue Objektinstanz auf den Value einer EntityReference festlegen.

Navigationseigenschaften definieren Beziehungen zwischen Objekten. Wenn das Objekt mit anderen Objekten im Objektkontext verbunden ist, sollten diese Eigenschaften festgelegt werden. Legen Sie beispielsweise die SalesOrderHeader-Beziehung eines neuen SalesOrderDetail-Objekts auf die Instanz des Auftrags fest, zu dem die Position gehört. Bei der Erstellung eines neuen Objekts, das mit einem anderen Objekt im Objektkontext verbunden ist, sollte das Objekt mit einer der folgenden Methoden hinzugefügt werden:

  • Rufen Sie für eine 1:n-Beziehung oder eine m:n-Beziehung Add von EntityCollection auf, und geben Sie die verbundenen Objekte an.

  • Legen Sie für eine 1:1-Beziehung oder eine m:1-Beziehung die Value-Eigenschaft von EntityReference auf das verbundene Objekt fest.

  • Rufen Sie die AddObject-Methode auf, um das neue Objekt dem Objektkontext hinzuzufügen, und definieren Sie anschließend die Beziehung mithilfe einer der beiden vorhergehenden Methoden.

Folgendes sollte beim Hinzufügen neuer Objekte beachtet werden:

  • Bevor SaveChanges aufgerufen wird, generiert Object Services einen temporären Schlüsselwert für jedes neue Objekt, das mithilfe der AddObject-Methode hinzugefügt wurde. Nach dem Aufruf von SaveChanges wird der Schlüsselwert durch den Identitätswert ersetzt, der beim Einfügen einer neuen Zeile von der Datenquelle zugewiesen wird.

  • Wenn die Datenquelle keinen Schlüsselwert für die Entität generiert, sollten Sie einen eindeutigen Wert zuweisen. Wenn zwei Objekte über denselben vom Benutzer festgelegten Schlüsselwert verfügen, wird beim Aufrufen von SaveChanges eine InvalidOperationException ausgelöst. In diesem Fall sollten eindeutige Werte zugewiesen und der Vorgang wiederholt werden.

  • Fremdschlüsselwerte werden von Entity Framework automatisch festgelegt, wenn Sie eine Beziehung zwischen Objekten definieren und SaveChanges aufrufen. Wenn eine Entität jedoch gespeicherten Prozeduren zum Einfügen, Aktualisieren und Entfernen zugeordnet wird, werden die Fremdschlüsselwerte nicht automatisch festgelegt. In diesem Fall müssen Sie die Eigenschaften, die dem Fremdschlüssel entsprechen, auf die richtigen Werte für das verbundene Objekt festlegen. Weitere Informationen finden Sie unter Unterstützung für gespeicherte Prozeduren (Entity Framework).

Ändern von Objekten

Wenn Sie Navigationseigenschaften oder skalare bzw. komplexe Eigenschaften eines Objekts ändern und SaveChanges aufrufen, werden Aktualisierungen an die Datenquelle gesendet. Sie können Beziehungen zwischen Objekten ändern, indem Sie Navigationseigenschaften wie den Wert einer EntityReference ändern oder indem Sie ein Objekt aus einer EntityCollection entfernen. Weitere Informationen finden Sie unter Gewusst wie: Ändern von Beziehungen zwischen Objekten (Entity Framework).

Object Services verfolgt mithilfe einer Instanz von IEntityChangeTracker Änderungen an Objekten nach, die an einen ObjectContext angefügt sind. Für jedes nachverfolgte Objekt existiert eine Instanz von IEntityChangeTracker. Abfragen geben Objekte in einem Unchanged-Zustand zurück. Dies gilt nicht, wenn die Abfrage eine auf NoTracking festgelegte MergeOption verwendet. Die Entitätsdatenmodell-Tools generieren Aufrufe von Methoden zur Änderungsnachverfolgung im Eigenschaftensetter jeder Eigenschaft eines Entitätstyps, wie beispielsweise im Eigenschaftensetter der Status-Eigenschaft in der SalesOrderHeader-Klasse.

Set(ByVal value As Byte)
    Me.OnStatusChanging(value)
    Me.ReportPropertyChanging("Status")
    Me._Status = Global.System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value)
    Me.ReportPropertyChanged("Status")
    Me.OnStatusChanged()
End Set
set
{
    this.OnStatusChanging(value);
    this.ReportPropertyChanging("Status");
    this._Status = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
    this.ReportPropertyChanged("Status");
    this.OnStatusChanged();
}

Die ReportPropertyChanging-Methode und die ReportPropertyChanged-Methode melden die Eigenschaftsänderungen an IEntityChangeTracker. Wenn Sie benutzerdefinierte Datenklassen mit einem Entitätsdatenmodell (EDM) verwenden, sollten Sie Eigenschaftsänderungen melden, damit diese durch Object Services nachverfolgt werden können. Weitere Informationen finden Sie unter Melden von Änderungen in benutzerdefinierten Datenklassen (Entity Framework).

Der Zustand eines Objekts wird von Unchanged zu Modified geändert, wenn ein Eigenschaftensetter aufgerufen wird. Dies ist auch dann der Fall, wenn der Wert, der festgelegt wird, dem aktuellen Wert entspricht. Nach dem Aufrufen der AcceptAllChanges-Methode wird der Status auf Unchanged zurückgesetzt. Standardmäßig wird während des SaveChanges-Vorgangs AcceptAllChanges aufgerufen.

Die Entitätsdatenmodell-Tools generieren außerdem zwei partielle Methoden, OnPropertyChanging und OnPropertyChanged. Diese Methoden werden im Eigenschaftensetter aufgerufen. Erweitern Sie diese Methoden in partiellen Klassen, um benutzerdefinierte Geschäftslogik bei Eigenschaftsänderungen einzufügen. Weitere Informationen finden Sie unter Gewusst wie: Ausführen von Geschäftslogik im Verlauf von Eigenschaftsänderungen (Entity Framework).

Folgendes sollte beim Ändern von Objekten beachtet werden:

  • Wird eine skalare oder komplexe Eigenschaft eines komplexen Objekts geändert, wird der Status des Entitätsobjekts der höchsten Ebene zu Modified geändert.

  • Änderungen werden nicht nachverfolgt, wenn Objekte in einem Detached-Zustand sind. Objekte befinden sich in diesem Zustand, wenn Sie von einer Abfrage zurückgegeben werden, die die NoTracking-Mergeoption verwendet, oder nachdem sie durch Aufrufen von Detach von einem ObjectContext getrennt wurden.

  • Sie können eine Beziehung zwischen zwei Objekten ändern, indem Sie einem neuen Objekt den EntityReference-Wert zuweisen. In diesem Fall aktualisiert Entity Framework beim Aufrufen von SaveChanges Fremdschlüsselwerte in der Datenquelle automatisch. Wenn eine Entität jedoch gespeicherten Prozeduren zum Einfügen, Aktualisieren und Entfernen zugeordnet ist, werden die Fremdschlüsselwerte nicht automatisch aktualisiert. In diesem Fall müssen Sie die Eigenschaften, die dem Fremdschlüssel entsprechen, auf die richtigen Werte für die neue Beziehung festlegen. Weitere Informationen finden Sie unter Unterstützung für gespeicherte Prozeduren (Entity Framework).

Löschen von Objekten

Durch Aufrufen der DeleteObject-Methode von ObjectContext wird das angegebene Objekt zum Löschen markiert. Die Zeile wird erst dann aus der Datenquelle gelöscht, wenn SaveChanges aufgerufen wird.

Folgendes sollte beim Löschen von Objekten beachtet werden:

  • Wenn ein Objekt gelöscht wird, werden alle Beziehungen zu anderen Objekten ebenfalls gelöscht.

  • Befinden sich zwei Objekte in einer eingeschränkten Beziehung, werden durch Löschen des übergeordneten Objekts alle untergeordneten Objekte ebenfalls gelöscht. Das Ergebnis ist das gleiche wie beim Aktivieren der CascadeDelete-Eigenschaft in der Zuordnung für die Beziehung. Weitere Informationen finden Sie unter Referenzielle Einschränkungen (Entity Framework).

  • Wenn ein von einer Abfrage zurückgegebenes Objekt mit einem oder mehreren Objekten verbunden ist, gibt die Abfrage immer Informationen zu diesen verbundenen Objekten zurück. Damit wird das Löschen von Objekten erleichtert. In einigen Fällen lösen die vorhandenen Informationen eine UpdateException aus, wenn Sie versuchen, ein Objekt zu löschen. Eine solche Ausnahme tritt z. B. auf, wenn in der Zuordnung, die die Beziehung definiert, das <OnDelete Action="Cascade" />-Element im übergeordneten Ende der Zuordnung angegeben ist. Wenn dies der Fall ist, laden Sie das verbundene Objekt explizit, bevor Sie die DeleteObject-Methode aufrufen.

  • Sie können die DeleteObject-Methode erneut für ein Objekt aufrufen, das bereits gelöscht wurde.

Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen, Ändern und Löschen von Objekten (Entity Framework).

Erstellen von Objekten in einer bestimmten EntitySet

Gelegentlich gehört ein Entitätstyp mehreren Entitätenmengen an. Eine Datenbank kann beispielsweise zwei Tabellen mit identischen Schemas enthalten. Dies kann der Fall sein, wenn die Daten partitioniert wurden, um einen effizienteren Datensicherungsprozess zu erreichen. Beispielsweise könnten Kundendaten in die Customer-Tabelle und die CustomerArchive-Tabelle partitioniert sein, wobei CustomerArchive über dasselbe Schema verfügt wie Customer, jedoch für Kunden verwendet wird, die seit mehr als sechs Monaten keine Aufträge mehr erteilt haben. Customer könnte jede Nacht gesichert werden, während CustomerArchive nur einmal wöchentlich gesichert wird. Für das Mapping müssen Customer und CustomerArchive verschiedenen Entitätenmengen angehören. Entity Framework unterstützt dieses Szenario, indem ein Entitätstyp in einer oder mehreren Entitätenmengen vorhanden sein kann. Weitere Informationen finden Sie unter Entitätenmengen (EDM).

Wenn ein Entitätstyp in mehreren Entitätenmengen vorhanden ist, ermöglicht Object Services das Hinzufügen neuer Instanzen des Typs zu einer bestimmten Entitätenmenge. Dazu muss der Wert von entitySetName angegeben werden, wenn die AddObject-Methode aufgerufen wird, um das Objekt dem Objektkontext hinzuzufügen. Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen eines Objekts zu einer bestimmten Entitätenmenge (Entity Framework).

Die Entitätsdatenmodell-Tools generieren außerdem auch AddToEntitySetName-Methoden für ObjectContext. Dabei gibt es für jede im konzeptionellen Modell definierte Entitätenmenge eine Methode. Diese Methoden rufen AddObject auf und übergeben den EntitySetName-Wert der entsprechenden Methode. Verwenden Sie diese Methoden, um Objekte bestimmten Entitätenmengen hinzuzufügen.

Siehe auch

Aufgaben

Gewusst wie: Definieren eines Modells mit mehreren Entitätenmengen pro Typ (Entity Framework)