Как изменить связи между сущностями POCO (платформа Entity Framework)
Если создание прокси-объектов отключено или сущность POCO была создана без прокси-объекта, то следует вызвать метод DetectChanges для ObjectContext, чтобы выполнить синхронизацию изменений с ObjectStateManager. Помимо обнаружения изменений в скалярных свойствах, этот метод также обнаруживает изменения связей, включая добавление, удаление и изменение связанных объектов. Дополнительные сведения см. в разделе Отслеживание изменений в сущностях POCO (платформа Entity Framework). Метод SaveChanges вызывает метод DetectChanges, поэтому явно вызывать метод DetectChanges не требуется, если немедленная синхронизация связей необязательна.
В примере из этого раздела используются пользовательские классы данных POCO, определенные в разделе Как определить сущности POCO (платформа Entity Framework), и модель данных на основе AdventureWorks, определенная в разделе Как настроить файлы моделирования и сопоставления для работы с пользовательскими объектами (платформа Entity Framework).
Пример
В этом примере текущий контакт для заказа заменяется на другой контакт. Метод DetectChanges вызывается методом SaveChanges до сохранения изменений в источнике данных.
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());
}
}