本文屬于OData系列
目錄
- 武裝你的WEBAPI-OData入門
- 武裝你的WEBAPI-OData便捷查詢
- 武裝你的WEBAPI-OData分頁查詢
- 武裝你的WEBAPI-OData資源更新Delta
- 武裝你的WEBAPI-OData之EDM
- 武裝你的WEBAPI-OData常見問題
- 武裝你的WEBAPI-OData使用Endpoint
- 武裝你的WEBAPI-OData聚合查詢
ODATA v4提出了新的聚合查詢功能,這對于ODATA的基本查詢能力($expand等)是一個非常大的補充,ODATA支持的聚合查詢功能,可以對資料進行統計分析,例如求和、平均值、最大/最小值、分組等,
聚合查詢是通過$apply
關鍵字實作的,使用$apply
關鍵字可以指定一系列的聚合操作,以對資料進行處理,
GET /odata/Products?$apply=groupby((Category), aggregate(Price with sum as TotalSales))
該請求將回傳按照產品類別(Category)分組的資料,并計算每個組的銷售總額(TotalSales),
需要注意,聚合查詢出來的結果一般都不在EDM中注冊,因此無法對結果應用更多ODATA查詢,如果想解鎖這個能力,請手動在EDM中注冊這個型別,
聚合查詢示例
ODATA的強大之處在于可以賦予前端更多的自主權,讓他們自己獲得自己需要的資料,通過聚合查詢,我們可以實作非常多復雜的、以前只能在后端單獨實作的查詢,舉例說明,我們有以下三個物體類,
public class AttachDeviceType
{
/// <summary>
///
/// </summary>
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
/// <summary>
/// 附加設備的型別
/// </summary>
public string Name { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
}
public abstract class AttachDeviceInfo
{
/// <summary>
///
/// </summary>
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string AttachDeviceId { get; set; }
public string Name { get; set; }
/// <summary>
/// 附加設備的型別
/// </summary>
public virtual AttachDeviceType AttachDeviceType { get; set; }
public string? Description { get; set; }
public virtual DeviceInfo DeviceInfo { get; set; }
}
public class DeviceInfo
{
/// <summary>
///
/// </summary>
[Key]
[MaxLength(200)]
public string DeviceId { get; set; }
/// <summary>
/// 地域位置的代碼
/// </summary>
public int? Adcode { get; set; }
public virtual ICollection<AttachDeviceInfo> AttachDevices { get; set; }
}
以上三個類定義了主設備、附加設備與從屬設備的型別,三者之間通過導航屬性進行連接,假定我們需要按照地域位置代碼進行分組查詢,查詢出每個地域的所有主設備的、附加設備的和不同的型別的數量,
/odata/DeviceInfos?$apply=groupby((Adcode), aggregate(AttachDevices/$count as NumAttachDevices, $count as NumDeviceInfos, AttachDevices/AttachDeviceType/$countdistinct as NumAttachDeviceTypes))
或者我們使用以attachdevice作為目標
/odata/AttachDeviceInfo?$apply=groupby((DeviceInfo/Adcode), aggregate(
$count as TotalDeviceInfo,
attachdevices/$count as TotalAttachDevices,
AttachDeviceType/$countdistinct as TotalAttachDeviceTypes))
思路沒有問題,但是實際執行會提示$count
不是可用的aggregatebinder之類的錯誤(Binding OData QueryNode of kind 'Count' is not supported by 'AggregationBinder'.),這是因為$count
已經是OData進行查詢得到的結果,這個結果不能在進行的聚合查詢了,
換一個思路,我們使用每一個物體物件的屬性作為統計物件,
odata/attachdeviceinfos?$apply=groupby((deviceinfo/Adcode), aggregate($count as NumAttachDevices, deviceinfo/deviceid with countdistinct as NumDevices, attachdevicetype/id with countdistinct as NumTypes))
那么就可以得到正確的結果:
[
{
"deviceInfo": {
"adcode": 110105
},
"NumTypes": 1,
"NumDevices": 1,
"NumAttachDevices": 2
},
{
"deviceInfo": {
"adcode": 110108
},
"NumTypes": 1,
"NumDevices": 1,
"NumAttachDevices": 1
}
]
當然,我們還可以組合使用filter查詢:
/odata/attachdeviceinfos?$apply=filter(deviceinfo/Adcode eq 110105)/groupby((deviceinfo/Adcode), aggregate($count as NumAttachDevices, deviceinfo/deviceid with countdistinct as NumDevices, attachdevicetype/id with countdistinct as NumTypes))
注意:在AXIOS中,前端發送如/之類的特殊字符會自動進行轉移,導致查詢請求失敗,請前端搜索禁止AXIOS自動轉移的方法,以保證發送的請求同POSTMAN發送的請求一致,
總結
使用聚合查詢可以方便將原來需要后端單獨編程的分類、統計等操作簡化,給予了前端非常大的自由度,同時減少了后端的介面數量,需要注意的是,很多操作在聚合查詢中語法可能有一些變化,請一定參閱ODATA的OASIS標準的檔案,
除非特殊說明,本作品由podolski創作,采用知識共享署名 4.0 國際許可協議進行許可,歡迎轉載,轉載請保留原文鏈接~喜歡的觀眾老爺們可以點下關注或者推薦~轉載請註明出處,本文鏈接:https://www.uj5u.com/net/548303.html
標籤:.NET技术