如何:更改 POCO 实体之间的关系(实体框架)

如果禁用代理对象的创建,或者创建的 POCO 实体不具有代理对象,则必须对 ObjectContext 调用 DetectChanges 方法,从而将更改与 ObjectStateManager 同步。 除检测标量属性中的更改外,此方法还检测关系中的更改,包括添加、删除、或更改相关对象。 有关更多信息,请参见跟踪 POCO 实体中的更改(实体框架)SaveChanges 方法调用 DetectChanges,从而如果您并不需要立刻同步关系,则无需显式调用 DetectChanges

本主题中的示例使用在如何:定义 POCO 实体(实体框架)中定义的 POCO 自定义数据类,和在如何:自定义建模和映射文件以使用自定义对象(实体框架)中定义的基于 AdventureWorks 的数据模型。

示例

本示例将一个订单的当前联系人更改为其他联系人。 在更改保存到数据源之前,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 实体(实体框架)