Silverlight 4.0 WCF RIA服务SP1,实体框架4,仅更新更改的列

Silverlight 4.0 WCF RIA服务SP1,实体框架4,仅更新更改的列,silverlight-4.0,entity-framework-4,wcf-ria-services,Silverlight 4.0,Entity Framework 4,Wcf Ria Services,我使用LinqToEntitiesDomainService类使用Silverlight 4客户端更新数据库。 实体框架ObjectContext有一个修改的扩展方法,允许您提供原始实体属性值: Order original = this.ChangeSet.GetOriginal(currentOrder); this.ObjectContext.Orders.AttachAsModified(currentOrder, original); 默认情况下,WCF RIA服务不会将原始值发送到

我使用LinqToEntitiesDomainService类使用Silverlight 4客户端更新数据库。 实体框架ObjectContext有一个修改的扩展方法,允许您提供原始实体属性值:

Order original = this.ChangeSet.GetOriginal(currentOrder);
this.ObjectContext.Orders.AttachAsModified(currentOrder, original);
默认情况下,WCF RIA服务不会将原始值发送到服务器,因此需要 将[RoundtripOriginal()]属性应用于他/她的实体

然而,即使我提供了原始值,实体框架生成的SQL也会更新所有列,而不仅仅是更改的列。由于AttachAsModified()方法不是本机ObjectContext类方法(它是在ObjectContextensions类中定义的扩展方法),所以我尝试使用 在ObjectSet类中定义的ApplyOriginalValues方法。没有变化。
最近发布的EntityFramework4.1似乎有解决方案(不确定)。实体框架4怎么样?是否可以生成sql以仅更新更改的列?

AttachAsModified将实体标记为已修改。随后(引用MSDN):

当您更改 要修改的实体对象条目,全部 对象的属性包括 标记为已修改,而不考虑 当前值或原始值

警告;我还没做过,但它应该能用

使用方法将实体标记为未更改,而不是使用AttachAsModified

然后对已更改的属性使用该方法,使其包含在更新中


编辑:如果您想找到一种方法来查找哪些属性已更改,那么下面有几篇文章解释了如何使用附件(如附件)进行更改。修改后的附件将实体标记为已修改。随后(引用MSDN):

当您更改 要修改的实体对象条目,全部 对象的属性包括 标记为已修改,而不考虑 当前值或原始值

警告;我还没做过,但它应该能用

使用方法将实体标记为未更改,而不是使用AttachAsModified

然后对已更改的属性使用该方法,使其包含在更新中


编辑:如果您想找到一种方法来查找哪些属性已更改,那么有几篇文章介绍了如何使用,例如我在MSDN论坛上问过类似的问题,并且确认WCF RIA服务将更改所有列。另一种选择是

您可以使用反射从数据库中获取副本,手动比较和标记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);
}

您可能需要根据情况更改代码,检查属性是否为只读,这只是一个示例,但它将帮助您在此基础上进行构建。

我曾在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);
}

您可能必须根据情况更改代码,检查属性是否为只读,这只是一个示例,但它将帮助您在其基础上进行构建。

我通过先附加对象,然后调用EntitySet上的ApplyOriginalValues来做到这一点。您需要一个具有原始值的对象来执行此操作。此方法还可用于防止列被更新,例如用于行级安全


注意:不幸的是,如果不首先从数据库中检索原始实体,这将不起作用。否则,只有设置为默认值的属性才会从更新中排除…

我通过先附加对象,然后调用EntitySet上的ApplyOriginalValues来实现这一点。您需要一个具有原始值的对象来执行此操作。此方法还可用于防止列被更新,例如用于行级安全


注意:不幸的是,如果不首先从数据库中检索原始实体,这将不起作用。否则,只有设置为默认值的属性才会被排除在更新之外…

谢谢,我想将您的答案标记为正确;所以不允许2个答案是正确的。非常欢迎,也没问题,@Akash的代码示例确实比我的MSDN引用更简单。=)谢谢你,我想把你的答案也标记为正确的;所以不允许2个答案是正确的。非常欢迎,也没问题,@Akash的代码示例确实比我的MSDN引用更简单。=)