WCF RIA Services SP1,实体框架4,仅更新已更改的列

|| 我使用LinqToEntitiesDomainService类通过Silverlight 4客户端更新数据库。 实体框架ObjectContext的AttachAsModified扩展方法可让您提供原始的实体属性值:
Order original = this.ChangeSet.GetOriginal(currentOrder);
this.ObjectContext.Orders.AttachAsModified(currentOrder, original);
默认情况下,WCF RIA Services不会将原始值发送到服务器,因此需要 将[RoundtripOriginal()]属性应用于他/她的实体。 但是,即使我提供原始值,由Entity Framework生成的SQL也会更新所有列,而不仅是更改的列。由于AttachAsModified()方法不是本机ObjectContext类方法(它是ObjectContextExtensions类中定义的扩展方法),因此我尝试使用 在ObjectSet类中定义的ApplyOriginalValues方法。不用找了。 看来最近发布的实体框架4.1可能有解决方案(不确定)。实体框架4呢? EF是否可以生成sql以仅更新更改的列?     
已邀请:
        我确实在MSDN论坛上提出了类似的问题,并且可以肯定WCF RIA Services将更改所有列。替代方法是 您可以从数据库中获取副本,使用反射手动比较和标记SetModifiedProperty。
// change state of entity as Unmodified/Unchanged...
original.EntityState = Unchanged;

// this is copy form database...
// Use different context
MyOrderContext context = new MyOrderContext();
Order dbOriginal = context.Orders.First( x=>x.OrderID == original.OrderID);

foreach(PropertyInfo p in copy.GetTypes().GetProperties()){
   Object originalValue = p.GetValue(dbOriginal);
   Object newValue = p.GetValue(original);
   if(originalValue!=null && newValue!=null 
       && originalValue.Equals(newValue)){
       continue;
   }
   // resetting this will 
   // make entity\'s only current
   // property as changed
   p.SetValue(original,originalValue);
   p.SetValue(original,newValue);
}
您可能需要根据情况更改代码,检查属性是否为只读,这只是一个示例,但是它将帮助您在此基础上进行构建。     
        AttachAsModified会将实体标记为已修改。随后(引自MSDN):   当您更改   实体对象条目全部为“已修改”   该对象的属性是   标记为已修改,无论   当前或原始值。 警告;我还没有做到这一点,但是应该可以。 不要使用AttachAsModified,而是使用ChangeState方法将实体标记为UnChanged。 然后,对已更改的属性使用SetModifiedProperty方法,以使其包含在更新中。 编辑:如果您想要一种方法来查找已更改的属性,有几篇文章在那里解释了如何使用ObjectStateManager这样的对象     
        通过首先附加对象,然后在EntitySet上调用ApplyOriginalValues,我设法做到了这一点。您将需要一个具有原始值的对象来执行此操作。此方法还可以用于防止列被更新,例如用于行级安全性。 注意:不幸的是,如果不先从数据库中检索原始实体,此方法将无法工作。否则,只会将设置为默认值的属性排除在更新之外...     

要回复问题请先登录注册