Gewusst wie: Ändern von Beziehungen zwischen POCO-Entitäten (Entity Framework)
Wenn die Erstellung von Proxyobjekten deaktiviert oder wenn eine POCO-Entität ohne das zugehörige Proxyobjekt erstellt wird, müssen Sie die DetectChanges-Methode für den ObjectContext-Kontext aufrufen, um die Änderungen mit dem ObjectStateManager zu synchronisieren. Diese Methode erkennt nicht nur Änderungen in skalaren Eigenschaften, sondern auch Änderungen in Beziehungen, wie das Hinzufügen, Löschen oder Ändern eines verknüpften Objekts. Weitere Informationen finden Sie unter Verfolgen von Änderungen in POCO-Entitäten (Entity Framework). Die SaveChanges-Methode ruft DetectChanges auf, deshalb müssen Sie DetectChanges nicht explizit aufrufen, wenn die Beziehungen nicht sofort synchronisiert werden müssen.
In dem Beispiel in diesem Thema werden die benutzerdefinierten POCO-Klassen verwendet, die in Gewusst wie: Definieren von POCO-Entitäten (Entity Framework) definiert sind, sowie ein auf AdventureWorks basierendes Datenmodell, das in Gewusst wie: Anpassen von Modellierungs- und Zuordnungsdateien zur Verwendung mit benutzerdefinierten Objekten (Entity Framework) definiert ist.
Beispiel
In diesem Beispiel wird der aktuelle Kontakt für eine Bestellung (order) in einen anderen Kontakt geändert. Die DetectChanges-Methode wird von der SaveChanges-Methode aufgerufen, bevor Änderungen in der Datenquelle gespeichert werden.
Using context As New POCOAdventureWorksEntities()
' Disable proxy object creation.
context.ContextOptions.ProxyCreationEnabled = False
Try
' Define the order and new address IDs.
Dim orderId As Integer = 43659
Dim differentContactID As Integer = 5
Dim order As Order = context.Orders.Include("Contact").Where(Function(o) o.SalesOrderID = orderId).First()
' Get contact to change to.
Dim differentContact As Contact = context.Contacts.First(Function(c) c.ContactID = differentContactID)
' The current contact.
Console.WriteLine("Original Contact Name: {0}", order.Contact.FirstName)
' The Entity Framework takes care of setting the other end of the relationship
' when you call DetectChanges or SaveChanges (which calls DetectChanges).
' However, there are scenarios when you are not working with ObjectContext
' and will want to fix both ends of the relationship yourself
' (for example, when working with disconnected objects).
' Change the current ContactID to the new ContactID.
order.ContactID = differentContact.ContactID
' Because the change tracking is not enabled
' The state manager will not be updated untill DetectChanges is called.
' If context.ContextOptions.ProxyCreationEnabled was set to true (which is the default)
' The changes would be synchronized righ away.
Console.WriteLine("The contact was updated, but DetectChanges was not yet called. ")
Console.WriteLine("Contact Name: {0}", order.Contact.FirstName)
context.DetectChanges()
Console.WriteLine("After DetectChanges was called. Contact Name: {0}", order.Contact.FirstName)
' Call save the changes, which calls DetectChanges.
context.SaveChanges()
Catch ex As UpdateException
Console.WriteLine(ex.ToString())
Catch ex As InvalidOperationException
Console.WriteLine(ex.ToString())
End Try
End Using
using (POCOAdventureWorksEntities context =
new POCOAdventureWorksEntities())
{
// Disable proxy object creation.
context.ContextOptions.ProxyCreationEnabled = false;
try
{
// Define the order and new address IDs.
int orderId = 43659;
int differentContactID = 5;
Order order =
context.Orders.Include("Contact")
.Where(o => o.SalesOrderID == orderId).First();
// Get contact to change to.
Contact differentContact = context.Contacts.
First(c => c.ContactID == differentContactID);
// The current contact.
Console.WriteLine("Original Contact Name: {0}", order.Contact.FirstName);
// The Entity Framework takes care of setting the other end of the relationship
// when you call DetectChanges or SaveChanges (which calls DetectChanges).
// However, there are scenarios when you are not working with ObjectContext
// and will want to fix both ends of the relationship yourself
// (for example, when working with disconnected objects).
// Change the current ContactID to the new ContactID.
order.ContactID = differentContact.ContactID;
// Because the change tracking is not enabled
// The state manager will not be updated untill DetectChanges is called.
// If context.ContextOptions.ProxyCreationEnabled was set to true (which is the default)
// The changes would be synchronized righ away.
Console.WriteLine("The contact was updated, but DetectChanges was not yet called. ");
Console.WriteLine("Contact Name: {0}", order.Contact.FirstName);
context.DetectChanges();
Console.WriteLine("After DetectChanges was called. Contact Name: {0}",
order.Contact.FirstName);
// Call save the changes, which calls DetectChanges.
context.SaveChanges();
}
catch (UpdateException ex)
{
Console.WriteLine(ex.ToString());
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}