Procedura: modificare le relazioni tra le entità POCO (Entity Framework)
Quando la creazione di oggetti proxy è disabilitata o quando un'entità POCO viene creata senza il relativo oggetto proxy, è necessario chiamare il metodo DetectChanges sull'oggetto ObjectContext per sincronizzare le modifiche con l'oggetto ObjectStateManager. Oltre a rilevare le modifiche nelle proprietà scalari, questo metodo consente di rilevare le modifiche nelle relazioni, incluse l'aggiunta, l'eliminazione o la modifica di un oggetto correlato. Per ulteriori informazioni, vedere Rilevamento delle modifiche nelle entità POCO (Entity Framework). Il metodo SaveChanges chiama il metodo DetectChanges, pertanto non è necessario chiamare il metodo DetectChanges in modo esplicito nel caso non occorra la sincronizzazione immediata delle relazioni.
Nell'esempio incluso in questo argomento vengono utilizzati le classi di dati personalizzate POCO definite in Procedura: definire entità POCO (Entity Framework) e un modello di dati basato su AdventureWorks definito in Procedura: personalizzare i file di mapping e di modellazione per l'utilizzo con oggetti personalizzati (Entity Framework).
Esempio
In questo esempio il contatto corrente per un ordine viene impostato su un contatto diverso. Il metodo DetectChanges viene chiamato dal metodo SaveChanges prima del salvataggio delle modifiche nell'origine dati.
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());
}
}