C# Simple.Odata.Client-Odata修补程序实体,只向服务器发送修改的属性

C# Simple.Odata.Client-Odata修补程序实体,只向服务器发送修改的属性,c#,wpf,odata,odata-v4,simple.odata.client,C#,Wpf,Odata,Odata V4,Simple.odata.client,我使用简单的Odata客户端在WPF应用程序中执行CRUD操作 我有一个父实体和一个子实体: public class Order { public int OrderId{get;set;} public int Description{get;set;} public ObservableCollection<OrderLine> OrderLines {get;set;} } public class OrderLine { public int

我使用简单的Odata客户端在WPF应用程序中执行CRUD操作

我有一个父实体和一个子实体:

public class Order
{
    public int OrderId{get;set;}
    public int Description{get;set;}
    public ObservableCollection<OrderLine> OrderLines {get;set;}
}
public class OrderLine
{
    public int OrderId{get;set;}
    public int OrderLineId{get;set;}
    public int ItenId{get;set;}
    public int ItemDescription{get;set;}
    public virtual Order Order {get;set;}
}
和子实体到DataGrid

DataGrid.ItemSource = Order.OrderLines;
当我单击GET按钮时,订单将从DB中获取。 然后我更改Order和OrderLines中的数据。 然后我删除一个订单行并添加两个新订单行

当我使用
observarbecollection
时,这些更改将自动从UI添加到源代码中

要求

单击“保存”按钮时,所有更改都应提交到服务器。(最好是批量请求)

问题


如何通过补丁请求只向服务器发送已更改的实体,而不发送标题和行中未修改的属性?

您在这里要求的是web服务和客户端框架的圣杯

OData中的补丁使得只接收和处理对象更改的属性成为可能,而且非常简单

但是,由客户机适当地构建数据包,这可以通过以下两种方式之一完成:

  • 发送前,客户端应将要发送的数据与上次检索的数据进行比较,以确定已更改的属性

  • 如果客户机上的数据包装在某种视图模型中,则视图模型可以跟踪(或监视)对属性所做的更改

  • 然后在发送时,客户端必须使用此信息来构建对象图的增量

    您还没有包含任何关于如何将URI生成到后端服务的信息,因此我不想猜测,但究竟是什么机制,上面两种策略中的一种需要实现

    如果您的后端是ODataV4服务,那么您可能会发现OData客户端包是一个有用的起点。请参阅和以下内容以生成客户端对象图:。您可以对实现OData v4规范的任何服务使用此选项,而不仅仅是在您控制后端代码时

    支持多种批处理模式,因为在ODataV4实现中,批处理的实现方式通常不同。出于这个原因,我将批处理排除在本次讨论之外,但我知道这些库在本机上支持批处理,并且工作得非常好

    有关生成类的用法示例,请参见此SO问题:或遵循我的单元测试之一:

        [TestMethod]
        public void TestPatch()
        {
            var client = ArcoCloud.Gateway.Client.Runtime.GetGatewayClient();
            var changeTracker = new Microsoft.OData.Client.DataServiceCollection<ArcoCloud.Gateway.Client.ArcoCloud_DataModel.Device>(client.Devices);
    
            // just change device 96
            var device = changeTracker.Single(d => d.Id == 96);
            device.Notes = "This is a test note to check if patch works natively";
    
            client.SaveChanges();
            /* Traced in Fiddler4
            PATCH: {
              "@odata.type": "#ArcoCloud_DataModel.Device",
              "Notes": "This is a test note to check if patch works natively"
            }*/
        }
    
    [TestMethod]
    公共void TestPatch()
    {
    var client=ArcoCloud.Gateway.client.Runtime.GetGatewayClient();
    var changeTracker=new Microsoft.OData.Client.DataServiceCollection

    如果您确实使用OData客户端库和生成的类,您可以轻松地查询数据服务,而无需使用DataServiceCollection,但是如果您这样做,更新会将整个对象图放入。您还将发现保存回更改的语法非常冗长且难以使用。这是出于设计考虑,要回写,您应该使用DataServiceCol选择。该框架提供简单查询机制,以便简化应用程序中的流程,查询/浏览/筛选数据可以与数据编辑窗口用于加载和保存数据的代码隔离

    这是微软通过C#code与OData v4服务交互的官方方式。T4模板的优点在于,您可以在需要时自定义模板或扩展生成的部分类,以便在重新生成类时不会覆盖您的业务逻辑


    如果需要,您可以使用自己的机制来支持这一点,只需记住这两个选项,或者在发生更改时跟踪更改,或者在保存之前使用比较来确定哪些字段已更改。

    您在这里要求的是web服务和客户端框架的圣杯

    OData中的补丁使得只接收和处理对象更改的属性成为可能,而且非常简单

    但是,由客户机适当地构建数据包,这可以通过以下两种方式之一完成:

  • 发送前,客户端应将要发送的数据与上次检索的数据进行比较,以确定已更改的属性

  • 如果客户机上的数据包装在某种视图模型中,则视图模型可以跟踪(或监视)对属性所做的更改

  • 然后在发送时,客户端必须使用此信息来构建对象图的增量

    您还没有包含任何关于如何将URI生成到后端服务的信息,因此我不想猜测,但究竟是什么机制,上面两种策略中的一种需要实现

    如果您的后端是OData v4服务,那么您可能会发现OData客户端包是一个有用的起点。请参阅和以下内容以生成客户端对象图:。您可以对实现OData v4规范的任何服务使用此功能,而不仅仅是在您控制后端代码时

    支持多种批处理模式,因为在OData v4实现中,批处理通常以不同的方式实现。因此,我将批处理排除在讨论之外,但我知道这些库本机支持批处理,并且工作得非常好

    有关生成类的用法示例,请参见此SO问题:或遵循我的单元测试之一:

        [TestMethod]
        public void TestPatch()
        {
            var client = ArcoCloud.Gateway.Client.Runtime.GetGatewayClient();
            var changeTracker = new Microsoft.OData.Client.DataServiceCollection<ArcoCloud.Gateway.Client.ArcoCloud_DataModel.Device>(client.Devices);
    
            // just change device 96
            var device = changeTracker.Single(d => d.Id == 96);
            device.Notes = "This is a test note to check if patch works natively";
    
            client.SaveChanges();
            /* Traced in Fiddler4
            PATCH: {
              "@odata.type": "#ArcoCloud_DataModel.Device",
              "Notes": "This is a test note to check if patch works natively"
            }*/
        }
    
    [TestMethod]
    公共void TestPatch()
    {
    var client=ArcoCloud.Gateway.client.Runtime.GetGatewayClient();
    var changeTracker=new Microsoft.OData.Client.DataServiceCollection

    如果您确实使用OData客户端库和生成的类,您可以轻松地查询数据服务,而无需使用DataServiceCollection,但是如果您这样做,更新会将整个对象图放回。您还将发现保存更改的语法非常冗长且难以使用。这是出于设计,是为了编写ba
        [TestMethod]
        public void TestPatch()
        {
            var client = ArcoCloud.Gateway.Client.Runtime.GetGatewayClient();
            var changeTracker = new Microsoft.OData.Client.DataServiceCollection<ArcoCloud.Gateway.Client.ArcoCloud_DataModel.Device>(client.Devices);
    
            // just change device 96
            var device = changeTracker.Single(d => d.Id == 96);
            device.Notes = "This is a test note to check if patch works natively";
    
            client.SaveChanges();
            /* Traced in Fiddler4
            PATCH: {
              "@odata.type": "#ArcoCloud_DataModel.Device",
              "Notes": "This is a test note to check if patch works natively"
            }*/
        }