方法: POCO エンティティ間のリレーションシップを変更 (Entity Framework)

プロキシ オブジェクトの作成が無効になっている場合やプロキシ オブジェクトなしで POCO エンティティが作成された場合、ObjectContextDetectChanges メソッドを呼び出して、変更をObjectStateManager と同期する必要があります。 このメソッドはスカラー プロパティの変更に加え、関連オブジェクトの追加、削除、変更を含むリレーションシップの変更も検出します。 詳細については、「POCO エンティティでの変更の追跡 (Entity Framework)」を参照してください。 SaveChanges メソッドは DetectChanges を呼び出すため、リレーションシップをすぐに同期する必要がない場合は明示的に DetectChanges を呼び出す必要はありません。

このトピックの例では、「方法: POCO エンティティを定義する (Entity Framework)」で定義された POCO カスタム データ クラスと「カスタム オブジェクトを操作できるようにモデリング ファイルとマッピング ファイルをカスタマイズする方法 (Entity Framework)」で定義された 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 エンティティの使用 (Entity Framework)