방법: POCO 엔터티 간 관계 변경(Entity Framework)
프록시 개체를 만들 수 없거나 POCO 엔터티가 프록시 개체 없이 만들어질 경우 ObjectContext의 DetectChanges 메서드를 호출하여 변경 내용을 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());
}
}