仅更新已修改的列

时间:2013-10-13 10:52:31

标签: wcf entity-framework odata

我使用EF和Oracle数据提供商为.Net提供OData服务(WCF数据服务5.6)。 当我跟踪从服务到数据库服务器的查询时,我发现即使我只修改了1列,UPDATE也包含表中的所有列。例如 - 我可以有5列的表,在客户端修改1并调用SaveChanges()。 在服务器端,在oracle中我得到

UPDATE col1 = x,col2 = x,col3 = x,col4 = x WHERE ....

我在网上看了很多关于这个问题,但仍然没有找到任何明确的解决方案。当然,我不是唯一一个有这个问题,但可能有人有想法如何 解决这个问题?

我看到EF6即将推出,WCF数据服务团队发布Alpha for EF6,但是,首先它仍然是alfa,EF6是RC,第二,它有一些问题,第三 - 不能保证同样的问题在新版本中不存在。

希望有人有正确答案......

2 个答案:

答案 0 :(得分:1)

好吧,我觉得至少有一种方法可以做到这一点。 在WCF服务中,在ChangeInterceptor中:

  [ChangeInterceptor("Entity")]
        public void OnChange(Entity item, UpdateOperations operations)
        {
            Dictionary<string, object> changes = new Dictionary<string, object>();
            foreach (String propName in this.CurrentDataSource.Entry(item).CurrentValues.PropertyNames)
            {
                if (this.CurrentDataSource.Entry(item).Property(propName).IsModified)
                    changes.Add(propName, this.CurrentDataSource.Entry(item).Property(propName).CurrentValue);
            }
            this.CurrentDataSource.Entry(item).State = System.Data.EntityState.Unchanged;
            var arrayOfAllChangedProps = changes.Keys.ToArray();
            foreach(string prop in arrayOfAllChangedProps)
                this.CurrentDataSource.Entry(item).Property(prop).CurrentValue = changes[prop];
            return;
        }

我们得到修改后的值,将它们添加到字典中(可以是任何其他集合),然后重置标志以修改状态。如果在此之前重置标志,那么我们无法进行更改。当标志复位时,在重置标志进行修改之前将当前值设置为保存的标志。

在完成所有这些之后,我们将看到只有修改过的列在UPDATE语句中。

我真的无法理解,为什么这不是默认行为?为什么所有这些魔法都应该完成。另外,我不知道这是否正确。但至少这对我有用。

答案 1 :(得分:0)

今天有效,我刚刚使用EF5和DS5.6在测试数据集上生成了这个SQL查询:

exec sp_executesql N'update [dbo].[People]
set [City] = @0
where ([Id] = @1)
',N'@0 nvarchar(max) ,@1 bigint',@0=N'Mashville',@1=1

OData查询:http://localhost:50000/People(1L)

OData有效负载:{ "City": "Mashville" }

也许您忘记使用HTTP PATCH方法而不是PUT