如何:检测 POCO 实体中的更改
本主题介绍如何通过使用更改跟踪代理跟踪 POCO 实体中的更改。 它还介绍如何在没有使用代理的情况下通过调用 DetectChanges 方法检测更改。 请注意,默认情况下 SaveChanges 方法将首先调用 DetectChanges 方法。 有关更多信息,请参见跟踪 POCO 实体中的更改(实体框架)。
本主题中的示例使用在如何:定义 POCO 实体(实体框架)中定义的 POCO 类,以及在如何:自定义建模和映射文件以使用自定义对象(实体框架)中定义的基于 AdventureWorks 的数据模型。
示例
此示例添加一个 POCO 自跟踪代理,它允许实体框架 跟踪 POCO 代理中的更改。
' Specify the order to update.
Dim orderId As Integer = 43680
Using context As New POCOAdventureWorksEntities()
Try
' Enable lazy loading.
context.ContextOptions.LazyLoadingEnabled = True
Dim order As Order = context.Orders.Where(Function(o) o.SalesOrderID = orderId).First()
' Create a new item and add it to the order.
' The Entity Framework is going to generate
' proxy object for the newItem object.
Dim newItem As LineItem = context.CreateObject(Of LineItem)()
newItem.SalesOrderDetailID = 0
' Assign the order to the new LineItem.
newItem.SalesOrderID = orderId
newItem.OrderQty = 1
newItem.ProductID = 750
newItem.UnitPriceDiscount = 0
newItem.UnitPrice = 2171.2942D
newItem.ModifiedDate = DateTime.Today
newItem.rowguid = Guid.NewGuid()
newItem.SpecialOfferID = 1
' Add the new item to the order.
' The order will be added to the context because
' we are working with POCO proxies.
order.LineItems.Add(newItem)
' The state of the newItem is Added.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State.ToString())
' Change the status and ship date of an existing order.
order.ShipDate = DateTime.Today
' The sate of the order item is Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(order).State.ToString())
' The newItem is set to Unchanged.
context.SaveChanges()
' Change the newly added item.
newItem.OrderQty = 2
' The changes are tracked as they occur and the state of the object is Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State.ToString())
' Delete the newly created object.
context.DeleteObject(newItem)
' Save changes in the object context to the database
' after first detecting changes again.
context.SaveChanges()
Catch ex As UpdateException
Console.WriteLine(ex.ToString())
Catch ex As InvalidOperationException
Console.WriteLine(ex.ToString())
End Try
End Using
// Specify the order to update.
int orderId = 43680;
using (POCOAdventureWorksEntities context =
new POCOAdventureWorksEntities())
{
try
{
// Enable lazy loading.
context.ContextOptions.LazyLoadingEnabled = true;
Order order = context.Orders.
Where(o => o.SalesOrderID == orderId).First();
// Create a new item and add it to the order.
// The Entity Framework is going to generate
// proxy object for the newItem object.
LineItem newItem = context.CreateObject<LineItem>();
newItem.SalesOrderDetailID = 0;
// Assign the order to the new LineItem.
newItem.SalesOrderID = orderId;
newItem.OrderQty = 1;
newItem.ProductID = 750;
newItem.UnitPriceDiscount = 0;
newItem.UnitPrice = 2171.2942M;
newItem.ModifiedDate = DateTime.Today;
newItem.rowguid = Guid.NewGuid();
newItem.SpecialOfferID = 1;
// Add the new item to the order.
// The order will be added to the context because
// we are working with POCO proxies.
order.LineItems.Add(newItem);
// The state of the newItem is Added.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State);
// Change the status and ship date of an existing order.
order.ShipDate = DateTime.Today;
// The sate of the order item is Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(order).State);
// The newItem is set to Unchanged.
context.SaveChanges();
// Change the newly added item.
newItem.OrderQty = 2;
// The changes are tracked as they occur and the state of the object is Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State);
// Delete the newly created object.
context.DeleteObject(newItem);
// Save changes in the object context to the database
// after first detecting changes again.
context.SaveChanges();
}
catch (UpdateException ex)
{
Console.WriteLine(ex.ToString());
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}
此示例添加一个 ObjectContext 不对其进行跟踪的 POCO 实体。 通过调用 DetectChanges 方法将 ObjectStateManager 与对象的当前状态同步。
' Specify the order to update.
Dim orderId As Integer = 43680
Using context As New POCOAdventureWorksEntities()
Try
' Disable proxy object creation.
context.ContextOptions.ProxyCreationEnabled = False
Dim order As Order = context.Orders.Include("LineItems").Where(Function(o) o.SalesOrderID = orderId).First()
' Create a new item and add it to the order.
' The Entity Framework is not going to generate
' a proxy object for the newItem object.
Dim newItem As New LineItem()
newItem.SalesOrderDetailID = 0
' Assign the order to the new LineItem.
newItem.SalesOrderID = orderId
newItem.OrderQty = 1
newItem.ProductID = 750
newItem.UnitPriceDiscount = 0
newItem.UnitPrice = 2171.2942D
newItem.ModifiedDate = DateTime.Today
newItem.rowguid = Guid.NewGuid()
newItem.SpecialOfferID = 1
' Add the new item to the order.
' The order will not be added to the context because
' we are working with pure POCO objects.
order.LineItems.Add(newItem)
Dim entry As ObjectStateEntry = Nothing
' There is no entry for the object because it is not in the context.
context.ObjectStateManager.TryGetObjectStateEntry(newItem, entry)
Console.WriteLine("{0}", If(entry IsNot Nothing, entry.State.ToString(),
"There is no entry for this object"))
' Call DetectChanges to synchronize the objects with the state manager.
context.DetectChanges()
' Try getting the entry after Detectchagnes was called.
context.ObjectStateManager.TryGetObjectStateEntry(newItem, entry)
Console.WriteLine("{0}", If(entry IsNot Nothing, entry.State.ToString(),
"There is no entry for this object"))
' Change the status and ship date of an existing order.
order.ShipDate = DateTime.Today
' Even though we changed the ShipDate of the item in the context
' the status of the order is still Unchanged.
' The changes to the POCO entity without the chane tracking proxy
' are not tracked as they occur.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(order).State.ToString())
' Calls DetectChanges(). The newItem is set to Unchanged.
context.SaveChanges()
' Change the newly added item.
newItem.OrderQty = 2
' The state of the newItem is Unchanged.
' If the newItem was a POCO proxy entity the changes would be tracked as they occur
' and the state would be Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State.ToString())
' Call DetectChanges to synchronize the objects with the state manager.
context.DetectChanges()
' The state of the newItem is now Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State.ToString())
' Delete the newly created object.
context.DeleteObject(newItem)
' Save changes in the object context to the database
' after first detecting changes again.
context.SaveChanges()
Catch ex As UpdateException
Console.WriteLine(ex.ToString())
Catch ex As InvalidOperationException
Console.WriteLine(ex.ToString())
End Try
End Using
// Specify the order to update.
int orderId = 43680;
using (POCOAdventureWorksEntities context =
new POCOAdventureWorksEntities())
{
try
{
// Disable proxy object creation.
context.ContextOptions.ProxyCreationEnabled = false;
Order order = context.Orders.Include("LineItems").
Where(o => o.SalesOrderID == orderId).First();
// Create a new item and add it to the order.
// The Entity Framework is not going to generate
// a proxy object for the newItem object.
LineItem newItem = new LineItem();
newItem.SalesOrderDetailID = 0;
// Assign the order to the new LineItem.
newItem.SalesOrderID = orderId;
newItem.OrderQty = 1;
newItem.ProductID = 750;
newItem.UnitPriceDiscount = 0;
newItem.UnitPrice = 2171.2942M;
newItem.ModifiedDate = DateTime.Today;
newItem.rowguid = Guid.NewGuid();
newItem.SpecialOfferID = 1;
// Add the new item to the order.
// The order will not be added to the context because
// we are working with pure POCO objects.
order.LineItems.Add(newItem);
ObjectStateEntry entry = null;
// There is no entry for the object because it is not in the context.
context.ObjectStateManager.TryGetObjectStateEntry(newItem, out entry);
Console.WriteLine("{0}", entry!=null ? entry.State.ToString() : "There is no entry for this object");
// Call DetectChanges to synchronize the objects with the state manager.
context.DetectChanges();
// Try getting the entry after Detectchagnes was called.
context.ObjectStateManager.TryGetObjectStateEntry(newItem, out entry);
Console.WriteLine("{0}", entry != null ? entry.State.ToString() : "There is no entry for this object");
// Change the status and ship date of an existing order.
order.ShipDate = DateTime.Today;
// Even though we changed the ShipDate of the item in the context
// the status of the order is still Unchanged.
// The changes to the POCO entity without the chane tracking proxy
// are not tracked as they occur.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(order).State);
// Calls DetectChanges(). The newItem is set to Unchanged.
context.SaveChanges();
// Change the newly added item.
newItem.OrderQty = 2;
// The state of the newItem is Unchanged.
// If the newItem was a POCO proxy entity the changes would be tracked as they occur
// and the state would be Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State);
// Call DetectChanges to synchronize the objects with the state manager.
context.DetectChanges();
// The state of the newItem is now Modified.
Console.WriteLine(context.ObjectStateManager.GetObjectStateEntry(newItem).State);
// Delete the newly created object.
context.DeleteObject(newItem);
// Save changes in the object context to the database
// after first detecting changes again.
context.SaveChanges();
}
catch (UpdateException ex)
{
Console.WriteLine(ex.ToString());
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}