デタッチされたオブジェクト対して行われた変更を適用する方法 (Entity Framework)

このトピックでは、オブジェクトのデタッチされたインスタンスに対して行われた同一オブジェクトの更新を適用する方法の例を示します。 この手順は、オブジェクトがリモートで更新され、変更を維持するためにサーバーに戻されたときに使用します。 オブジェクトがサーバーのオブジェクト コンテキストに単純にアタッチされた場合、そのオブジェクトが既にオブジェクト コンテキスト内にあると、更新が失われるか、操作が失敗します。 これは、オブジェクトは Unchanged 状態でアタッチされるために発生します。 詳細については、「オブジェクトのアタッチとデタッチ (Entity Framework)」を参照してください。

The example in this topic is based on the Adventure Works Sales Model. To run the code in this example, you must have already added the AdventureWorks Sales Model to your project and configured your project to use the Entity Framework. To do this, complete the procedures in Entity Framework プロジェクトを手動で構成する方法 and 方法: モデル ファイルとマッピング ファイルを手動で定義する (Entity Framework).

次の例では、更新された SalesOrderDetail オブジェクトが元のオブジェクトと共に UpdateItemChanges メソッドに渡されます。 その結果、オブジェクトに対してクエリを実行したり、オブジェクトをメモリに保持したりせずに、変更を適用できます。 また、クライアントに渡してもらうことを要求せずにデータベースから元のオブジェクトを取得することもできます。

Private Shared Sub ApplyItemUpdates(ByVal originalItem As SalesOrderDetail, ByVal updatedItem As SalesOrderDetail)
    Using context As New AdventureWorksEntities()
        context.SalesOrderDetails.Attach(updatedItem)
        ' Check if the ID is 0, if it is the item is new. 
        ' In this case we need to chage the state to Added. 
        If updatedItem.SalesOrderDetailID = 0 Then
            ' Because the ID is generated by the database we do not need to 
            ' set updatedItem.SalesOrderDetailID. 
            context.ObjectStateManager.ChangeObjectState(updatedItem, System.Data.EntityState.Added)
        Else
            ' If the SalesOrderDetailID is not 0, then the item is not new 
            ' and needs to be updated. Because we already added the 
            ' updated object to the context we need to apply the original values. 
            ' If we attached originalItem to the context 
            ' we would need to apply the current values: 
            ' context.ApplyCurrentValues("SalesOrderDetails", updatedItem); 
            ' Applying current or original values, changes the state 
            ' of the attached object to Modified. 
            context.ApplyOriginalValues("SalesOrderDetails", originalItem)
        End If
        context.SaveChanges()
    End Using
End Sub
private static void ApplyItemUpdates(SalesOrderDetail originalItem,
    SalesOrderDetail updatedItem)
{
    using (AdventureWorksEntities context =
        new AdventureWorksEntities())
    {
        context.SalesOrderDetails.Attach(updatedItem);
        // Check if the ID is 0, if it is the item is new. 
        // In this case we need to chage the state to Added.
        if (updatedItem.SalesOrderDetailID == 0)
        {
            // Because the ID is generated by the database we do not need to
            // set updatedItem.SalesOrderDetailID.
            context.ObjectStateManager.ChangeObjectState(updatedItem, System.Data.EntityState.Added);
        }
        else
        {
            // If the SalesOrderDetailID is not 0, then the item is not new
            // and needs to be updated. Because we already added the 
            // updated object to the context we need to apply the original values.
            // If we attached originalItem to the context 
            // we would need to apply the current values:
            // context.ApplyCurrentValues("SalesOrderDetails", updatedItem);
            // Applying current or original values, changes the state 
            // of the attached object to Modified.
            context.ApplyOriginalValues("SalesOrderDetails", originalItem);
        }
        context.SaveChanges();
    }
}

参照

概念

N 層アプリケーションのビルド (Entity Framework)
オブジェクトのシリアル化 (Entity Framework)
オブジェクトのアタッチとデタッチ (Entity Framework)
オブジェクトの使用 (Entity Framework)