用于字段级别更新的 WCF 合同

发布于 2024-08-19 08:51:14 字数 128 浏览 4 评论 0原文

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

在不简单发送键值对字典的情况下,为这种场景设计数据契约的最佳方法是什么?

I'm developing an application that does some CRUD operations through a WCF service. The read method returns a complete entity, the update is performed through a legacy system, and only the changed values should be updated.

What is the best way to design the data contract for this scenario without simply sending a dictionary of key-value pairs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

再可℃爱ぅ一点好了 2024-08-26 08:51:14

我唯一能想到的另一件事是使您的组件 持久 - 即将其状态保留到文件或数据库。这样,在更新时,您可以将先前的状态与传入的状态进行比较。我不确定这是一个好方法,因为它会比仅传入键值对带来更多的开销。

从外面看,它可能看起来更 CRUDy 或其他什么,但从实际的角度来看,您最好只传递一些有关哪些值发生了变化的指示。

The only other thing I can think of is to make your component durable - i.e. persist its state to a file or database. That way, on the update you can compare the previous state to the state being passed in. I'm not sure that's a good way to go since it will introduce more overhead than just passing in the key-value pairs.

From the outside it might look more CRUDy or whatever, but from a practical standpoint you may be better off just passing some indication as to which values changed.

贵在坚持 2024-08-26 08:51:14

如果它有帮助,但不确定您到底在寻找什么...

在更新请求中,仅对不为空的字段进行操作。

此外,将所有不可为空的类型包装在可为空的结构中。

举个例子...

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;
}

In case it helps, not sure exactly what you're looking for though ...

In the update request, only act upon fields that are not null.

In addition wrap any non-nullable types in a nullable structure.

As an example ...

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;
}
难如初 2024-08-26 08:51:14

最好的方法是使用属性字典,只需将您的实体表示为属性名称和值的字典即可。
将所有更改保存在某个列表中,并传递包含所有更改属性的部分字典。

我认为这是最好的设计,

如果您想避免这种设计,请发送整个实体以及一些已更改属性的列表。
(为了节省传输,您可以在其他属性上设置 null)

如果您不想更改服务合同签名,您可以将修改后的属性的名称推送到标头上

the best way to do this is with property dictionary, just represent your entities as dictionary of property name and value.
save all changes in some list and pass a partial dictionary with all changed properties.

i think this is best design,

if u wanna avoid this design, send entire entity with some list of changed properties.
(to save transport u can put null on other properties)

if u don't wanna change the service contract signature u can push the names of modified properties on the header

美煞众生 2024-08-26 08:51:14

对于如何实现这一目标,我有两个想法;

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

    让客户端完整发送

  2. 使用类似于 Nullable 的模式,我们将其称为 Modified,带有 IsModified 标志和 T 类型的 NewValue 属性。DataContract 的每个属性都属于这种类型,服务可以在执行更新时检查 IsModified 标志。< /p>

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

I had two ideas of how to achieve this;

  1. Have the client send both the original entity, and the changed entity in full, the service would then figure out what properties were changed.

  2. Use a pattern similar to Nullable, lets call it Modified with an IsModified flag and a NewValue property of type T. Each property of the DataContract would be of this type, the service can check the IsModified flag when performing the update.

The legacy sytem we use has an api that accepts String.Empty to identify unmodified fields, a '?' character is used to indicate an update to an empty string. I really don't like this, the user of the api is forced to read the documentation, and if you actually want to store a '?' you can't. I want our webservice api to be more explicit.

梦里泪两行 2024-08-26 08:51:14

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

You can use DataSet to keep your changes. Call your record as DataSet then assign some values to the record. DataSet.Tables[0].GetChanges() will give you the columns which were changed.

无人问我粥可暖 2024-08-26 08:51:14

您可以保留数据合同并更新您的服务合同。只需将方法的必填字段表示为服务契约中的属性即可。如果服务联系人发生变化,任何使用该服务的消费应用程序都必须进行更新,但消费应用程序将知道成功更新数据需要什么。

这种方法有优点和缺点,但当我编写的方法不需要完整的数据契约时,我会使用它。

--已编辑拼写错误--

You could leave the data contract alone and update your service contract. Just represent the required fields for the method as properties within the service contract. Any consuming application using the service will have to be updated if the service contact changes, but the consuming application will know what is required to successfully update the data.

There are positives and negatives to this method, but I use it when a method I am writing doesn't require the full data contract.

--Edited for a spelling error--

拥抱影子 2024-08-26 08:51:14

查看您的要求和声明,在开始编写我对可能的解决方案的看法之前,我做了一些假设:

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

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

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

发送原件和从客户端到服务器的状态更改是一种可能但繁重的解决方案。除此之外,客户端对此信息不感兴趣,服务器感兴趣。

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

Looking at your requirements and statements, i've made a few assumptions before starting to write my vision on a possible solution:

  • You are using the same class for retrieving (return value type of "read" operation) and updating an item (input parameter type of "update" operation) in your WCF service.
  • Your current problem of implementation is how to use the original class (not a dictionary) AND still be able to determine 'what has changed compared to the read' when you get the "Update" operation called on your WCF service
  • You are writing both the server and client. Both are written using the MS .Net framework.

If this is true, the problem lies in the Update method missing information. The information required is 'has changed' which could be inferred if a 2nd state is present to compare against or should already be present along side the state to update in the back-end.

Since you only have the 'back-end state' (without flags) when the client posts its data to the WCF service, how should we determine what did change? Obviously, we want to prevent another 'read' roundtrip to get the current server state and start comparing.

Sending the original & changed state from the client to the server is a possible but heavy solution. Next to that, the client isn't interrested in this information, the server is.

Adding this all up makes my guess is that changing the type of the 'Update' operation input parameter is the easiest way to go. Create a decorator class that adds 'dirty bit' behavior to the original entity. Use this new class as input parameter for your "Update" operation. You then will have the availability in the server to check this dirty bit next to the full state send by the client. The major change on the client side is that the object needed for the 'Update' operation is no longer the same as the one provided by the 'Read' method. To eleviate this pain, i would probably create a decorator class which added the required 'dirty bit' handling. This only requires the object instanciation to change, while maintaining the interface signature for the client (very little code changes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文