2011-06-13 86 views
1

我使用LinqToEntitiesDomainService类来更新Silverlight 4客户端的数据库。 还有的AttachAsModified为实体框架ObjectContext的扩展方法,它允许您提供原始的实体属性值:WCF RIA Services SP1,实体框架4,仅更新更改的列

Order original = this.ChangeSet.GetOriginal(currentOrder); 
this.ObjectContext.Orders.AttachAsModified(currentOrder, original); 

默认情况下,WCF RIA服务不发送原始值到服务器,所以人们需要 应用[RoundtripOriginal( )]属性给他/她的实体。

但是,即使我提供原始值,由Entity框架生成的SQL更新所有列,不仅更改了所有列。由于AttachAsModified()方法不是本地ObjectContext类方法(它是在ObjectContextExtensions类中定义的扩展方法),因此我尝试使用在ObjectSet类中定义的ApplyOriginalValues方法 。不用找了。 看来最近发布的实体框架4.1可能有解决方案(不确定)。实体框架4如何? EF有可能生成sql来只更新更改的列吗?

回答

1

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

您可能需要更改代码,每情况,检查是否属性是只读与否,这只是一个样本,但它会帮助你建立在其上。

3

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

当更改 实体对象条目修改时,对象的属性的所有 被 标记为修改,无论 电流或原始值的EntityState。

警告;我没有这样做,但是,它应该工作。

不使用AttachAsModified,而是使用ChangeState方法将实体标记为UnChanged。

然后在已更改的属性上使用SetModifiedProperty方法使它们包含在更新中。

编辑:如果你想办法找到其性质已经改变,有一对夫妇的文章在那里解释如何使用做ObjectStateManagerthis one

+0

谢谢,我想标记你的答案也是正确的; SO不允许2个答案是正确的。 – synergetic 2011-06-14 00:06:52

+0

大多数欢迎和没有问题,@阿卡什的代码示例确实比我的MSDN报价更容易。 =) – Smudge202 2011-06-14 08:10:10

1

我设法做到这一点,首先附加对象,然后在EntitySet上调用ApplyOriginalValues。你需要一个具有原始值的对象来做到这一点。该方法也可以用来防止列被更新,例如为行级安全性。

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