Как изменить связи между сущностями 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());
    }
}

См. также

Основные понятия

Работа с сущностями POCO (платформа Entity Framework)