簡體   English   中英

Simple.Odata.Client-通過僅將修改后的屬性發送到服務器來實現Odata修補程序實體

[英]Simple.Odata.Client - Odata Patch Entity by only sending modified properties to server

我正在使用簡單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;}
}

我有一個執行粗操作的類:

public class ManageOrders
{
    //Implements INotifyPropertyChanged
    Public Order Order;

    public void Get()
    {
        this.Order = packages = await client
                    .For<Order>()
                    .ByKey(1001).
                    .Expand(x.OrderLines).
                    .FindEntriesAsync();
    }

    public void Save()
    {
        if("NEW")
        {
            // Add new item and save
        }
        if("MODIFIED")
        {
            // save modified item
        }
    }

    public void Delete()
    {
        //Delete
    }   
}

在此處輸入圖片說明

我將父實體屬性綁定到標題控件。

TextBox.Text = Order.Description;

和子實體到DataGrid。

DataGrid.ItemSource = Order.OrderLines;

當我單擊GET按鈕時,將從數據庫中獲取訂單。 然后,我更改Order和OrderLines中的數據。 然后,我刪除一個OrderLine並添加兩個新的OrderLines。

當我使用ObservarbleCollection ,更改將自動從UI添加到Source。

需求

當我單擊“保存”按鈕時,所有更改都應提交到服務器。 (最好是批處理請求)。

如何通過PATCH請求僅將更改的實體發送到服務器,而不在標頭和行中發送未修改的屬性?

您在這里要問的是IMO是Web服務和客戶端框架的聖杯。

OData中的修補程序使得僅接收和處理對象的已更改屬性成為可能並且變得簡單。

但是,由客戶端來適當地構建數據包,可以通過以下兩種方法之一來完成:

  1. 在發送之前,客戶端應將要發送的數據與最后檢索到的數據進行比較,以確定已更改的屬性。

  2. 如果客戶端上的數據包裝在某種視圖模型中,則視圖模型可以跟蹤(或監視)對屬性所做的更改。

然后在發送時,客戶端必須使用此信息來構建對象圖的增量。

您還沒有提供有關如何為后端服務生成URI的任何信息,所以我不想猜測,但是無論哪種機制,都需要實現上述兩種策略中的一種。

如果您的后端是OData v4服務,那么您可能會發現OData Client軟件包是一個有用的起點。 請參閱用於.NET的OData客戶端庫和以下內容以生成客戶端對象圖: OData v4客戶端代碼生成器 您可以將其用於實現OData v4規范的任何服務,不僅是在控制后端代碼時。

支持批處理的多種模式,因為批處理通常在OData v4實現中以不同的方式實現。 因此,在本次討論中我不再進行批處理,但是知道這些庫本身支持批處理,並且效果很好。

有關使用生成的類的示例,請參見以下SO問題: 從Web api 2中的odata客戶端調用補丁的正確方法是什么?或者遵循我的單元測試之一:

    [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"
        }*/
    }

請注意,要使客戶端僅發送修改后的屬性,請使用從ObservableCollection繼承的Microsoft.OData.Client.DataServiceCollection,但它還具有在內部跟蹤查詢中對象更改的其他好處。 請參見DataServiceCollection類

如果確實使用OData客戶端庫和Generated類,則可以在沒有DataServiceCollection的情況下輕松查詢數據服務,但是如果這樣做,則更新將放置整個對象圖。 您還會發現將更改保存回來的語法非常羅and並且難以使用。 這是設計使然,要回寫您應該使用DataServiceCollection。 該框架提供了簡單的查詢機制,因此您可以簡化應用程序中的過程,可以將查詢/瀏覽/過濾數據與數據編輯窗口可能用於加載和保存其數據的代碼隔離開。

這是通過C#代碼與OData v4服務進行交互的官方MS方法。 T4模板的優點在於,您可以在需要的地方自定義模板,或者擴展生成的部分類,以便在重新生成類時不會覆蓋業務邏輯。

如果需要,您可以滾動自己的機制來支持此操作,只需記住兩個選項,要么跟蹤更改的發生,要么在保存之前使用比較來確定哪些字段已更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM