字段级更新的WCF合同

时间:2010-01-22 18:45:54

标签: c# wcf architecture contracts

我正在开发一个通过WCF服务执行某些CRUD操作的应用程序。 read方法返回一个完整的实体,更新是通过遗留系统执行的,只应更新更改的值。

在不简单地发送键值对字典的情况下,为此场景设计数据协定的最佳方法是什么?

7 个答案:

答案 0 :(得分:1)

我唯一能想到的是制作组件durable - 即将其状态保存到文件或数据库中。这样,在更新时,您可以将之前的状态与传入的状态进行比较。我不确定这是一个好的方法,因为它会引入更多的开销,而不仅仅是传递键值对。

从外面看它可能看起来更粗糙或者其他什么,但从实际的角度来看,你可能最好只是传递一些关于哪些值发生变化的指示。

答案 1 :(得分:1)

如果它有帮助,不确定你到底想要什么......

在更新请求中,仅对非空的字段执行操作。

另外将任何非可空类型包装在可以为空的结构中。

作为一个例子......

Update( Nullable<int> orderNumber, 
        Nullable<DateTime> orderDate, 
        Nullable<bool> isComplete )
{
    if( orderNumber != null )
        databaseRecord.OrderNumber = orderNumber;

    if( orderDate != null )
       databaseRecord.OrderDate = orderDate;

    if( isComplete != null )
       databaseRecord.IsComplete = isComplete;
}

答案 2 :(得分:0)

执行此操作的最佳方法是使用属性字典,只需将您的实体表示为属性名称和值的字典。 保存某些列表中的所有更改,并传递包含所有已更改属性的部分字典。

我认为这是最好的设计,

如果你想避免这种设计,请向整个实体发送一些已更改属性的列表。 (为了保存传输,你可以将null放在其他属性上)

如果您不想更改服务合同签名,您可以在标题上推送已修改属性的名称

答案 3 :(得分:0)

我有两个如何实现这个目标的想法;

  1. 让客户端完整地发送原始实体和已更改的实体,然后服务会找出哪些属性已更改。

  2. 使用类似于Nullable的模式,让我们使用IsModified标志和类型T的NewValue属性调用它.DataContract的每个属性都是这种类型,服务可以在执行时检查IsModified标志更新

  3. 我们使用的遗留系统有一个api,它接受String.Empty来识别未修改的字段,'?' character用于表示对空字符串的更新。我真的不喜欢这个,api的用户被迫阅读文档,如果你真的想存储'?'你不能。我希望我们的webservice api更加明确。

答案 4 :(得分:0)

您可以使用DataSet来保留更改。将您的记录称为DataSet,然后为记录分配一些值。 DataSet.Tables [0] .GetChanges()将为您提供已更改的列。

答案 5 :(得分:0)

您可以单独保留数据合同并更新服务合同。只需将方法的必填字段表示为服务合同中的属性即可。如果服务联系人发生更改,则必须更新使用该服务的任何消费应用程序,但消费应用程序将知道成功更新数据所需的内容。

这种方法有正面和负面的,但是当我写的方法不需要完整的数据合同时,我会使用它。

- 编辑拼写错误 -

答案 6 :(得分:0)

看看你的要求和陈述,我在开始写一个可能的解决方案的愿景之前做了一些假设:

  • 您正在使用相同的类来检索(返回值类型的“读取”操作)并更新WCF服务中的项目(“更新”操作的输入参数类型)。
  • 您当前的实施问题是如何使用原始类(而不是字典)并且当您获得在WCF服务上调用的“更新”操作时,仍然能够确定“与读取相比发生了哪些变化”
  • 您正在编写服务器和客户端。两者都是使用MS .Net框架编写的。

如果是这样,问题在于Update方法缺少信息。所需的信息是“已更改”,如果存在第二个状态以进行比较或者应该已经存在于状态的一侧以便在后端更新,则可以推断出该信息。

由于当客户端将其数据发布到WCF服务时,您只有“后端状态”(没有标志),我们应该如何确定更改的内容?显然,我们希望阻止另一个“读取”往返来获取当前服务器状态并开始比较。

发送原件&amp;将状态从客户端更改为服务器是一种可能但重要的解决方案。接下来,客户端不会对此信息感兴趣,服务器就是。

添加这一点使我的猜测是改变'Update'操作输入参数的类型是最简单的方法。创建一个装饰器类,将“脏位”行为添加到原始实体。使用此新类作为“更新”操作的输入参数。然后,您将具有服务器中的可用性,以检查客户端发送的完整状态旁边的脏位。客户端的主要变化是“更新”操作所需的对象不再与“读取”方法提供的对象相同。为了提升这种痛苦,我可能会创建一个装饰器类,它添加了所需的“脏位”处理。这只需要对象instanciation进行更改,同时保持客户端的接口签名(代码更改很少)。