EF4在N-Tier下的应用:中间层如何更新实体

http://www.cnblogs.com/hackee/archive/2009/11/16/1603934.html

 在多层应用(N-Tier)环境中,如何更新对象是一个复杂的话题。在这篇文章中,讨论了最新的ADO.NET Entity Framework 4 Beta 2(以下简称EF4)如何实现在多层应用中,中间层如何完成对象的更新操作。下面例子对于Web应用(如ASP.NET MVC)来说尤其具有参考价值,因为在Web环境下,中间层和客户端无法共享实体对象,因而无法利用跟踪实体发生的变化。

新的EF4为多层应用环境提供了许多新的工具和方法,包括:ApplyCurrentValuesApplyOriginalValues,SetModifiedProperty,GetUpdatableOriginalValuesCurrentValues属性,等等。例如,EF 1中,如果需要将实体标记为”修改“状态,需要在实体本身以及实体的各个属性上均调用SetModified,现在仅需要调用ObjectStateManager的ChangeObjectState,便可以将一个Attached实体的所有属性均标记为”修改“状态。

例子

下面的例子中,Product实例的新旧值均传递给了UpdateProductChanges方法 ,这样可以避免到数据库中查询或在内存中保存待更新对象的旧值。对于ASP.NET MVC,originalProduct对象可以保存在Form的某个Hidden元素中,提交Form时将其一并传递给Action。    

 

 

 

  下面的例子展示了在没有给出旧的对象的情况下,如何进行对象更新 : 


 1 private static void ApplyProductUpdates(Product updatedProduct)
 2 {
 3     // Define an ObjectStateEntry and EntityKey for the current object.
 4     EntityKey key;
 5     object originalProduct;
 6 
 7     using (NorthwindEntities northwindContext =
 8         new NorthwindEntities())
 9     {
10         try
11         {
12             // Create the detached object's entity key.
13             key = northwindContext.CreateEntityKey("Products", updatedProduct);
14 
15             // Get the original item based on the entity key from the context
16             // or from the database.
17             if (northwindContext.TryGetObjectByKey(key, out originalProduct))
18             {
19                 // Call the ApplyCurrentValues method to apply changes
20                 // from the updated item to the original version.
21                 northwindContext.ApplyCurrentValues(
22                     key.EntitySetName, updatedProduct);
23             }
24 
25             northwindContext.SaveChanges();
26         }
27         catch (InvalidOperationException ex)
28         {
29             Console.WriteLine(ex.ToString());
30         }
31     }
32 }

 

 [更新]

在上面的第二种方法中,实体的原值是从数据库或当前Context中获取的,在ASP.NET MVC中,往往是在Action中创建一个新的Context,在这种应用环境下,原值基本上都是从数据库中获取。有什么方法能够既不需要提供实体的原值,也能够避免从数据库中检索原值所带来的额外负载呢?

新的EF4为我们提供了一个便捷的方法,

 


 1 private static void ApplyProductUpdates(Product updatedProduct) {
 2     using (NorthwindEntities northwindContext = new NorthwindEntities()) {
 3         try {
 4             northwindContext.Attach(updatedProduct);
 5             northwindContext.ObjectStateManager.ChangeObjectState(updatedProduct, EntityState.Modified);
 6 
 7             northwindContext.SaveChanges();
 8         }
 9         catch (InvalidOperationException ex) {
10             Console.WriteLine(ex.ToString());
11         }
12     }
13 }

 

而在EF1中,则需要这样:

 


 1 private static void ApplyProductUpdates(Product updatedProduct) {
 2     using (NorthwindEntities northwindContext = new NorthwindEntities()) {
 3         try {
 4             northwindContext.Attach(updatedProduct);
 5             var stateEntry = context.ObjectStateManager.GetObjectStateEntry(updatedProduct);
 6             foreach (var propertyName in from fm in stateEntry.CurrentValues.DataRecordInfo.FieldMetadata select fm.FieldType.Name) {
 7               stateEntry.SetModifiedProperty(propertyName);
 8             }
 9 
10             northwindContext.SaveChanges();
11         }
12         catch (InvalidOperationException ex) {
13             Console.WriteLine(ex.ToString());
14         }
15     }
16 }

 

 


 1 private static void ApplyProductUpdates(Product originalProduct,
 2     Product updatedProduct)
 3 {
 4     using (NorthwindEntities northwindContext =
 5         new NorthwindEntities())
 6     {
 7         try
 8         {
 9             // Attach the original item to the object context.
10              northwindContext.Attach(originalProduct);
11 
12             // Call the ApplyCurrentValues method to apply changes
13             // from the updated item to the original version.
14              northwindContext.ApplyCurrentValues("Products",
15                 updatedProduct);
16 
17             northwindContext.SaveChanges();
18         }
19         catch (InvalidOperationException ex)
20         {
21             Console.WriteLine(ex.ToString());
22         }
23     }
24 }

 

 

posted on 2010-08-07 11:48  kis$ove  阅读(487)  评论(0编辑  收藏  举报

导航