武裝你的WEBAPI-OData聚合查詢

来源:https://www.cnblogs.com/podolski/archive/2023/03/27/17261079.html
-Advertisement-
Play Games

本文屬於OData系列 目錄 武裝你的WEBAPI-OData入門 武裝你的WEBAPI-OData便捷查詢 武裝你的WEBAPI-OData分頁查詢 武裝你的WEBAPI-OData資源更新Delta 武裝你的WEBAPI-OData之EDM 武裝你的WEBAPI-OData常見問題 武裝你的WE ...


本文屬於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 國際許可協議進行許可。歡迎轉載,轉載請保留原文鏈接~喜歡的觀眾老爺們可以點下關註或者推薦~
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • TiDB 基礎使用 TiDB dashboard使用 TiDB Dashboard 是 TiDB 自 4.0 版本起提供的圖形化界面,可用於監控及診斷 TiDB 集群。TiDB Dashboard 內置於 TiDB 的 PD 組件中,無需獨立部署。 集群概況 查看集群整體 QPS 數值、執行耗時、消 ...
  • python中index()、find()方法,具體內容如下: index() 方法檢測字元串中是否包含子字元串 str ,該方法與 python find()方法一樣,只不過如果str不在 string中會報一個異常。影響後面程式執行 index()方法語法:str.index(str, beg= ...
  • 基於.NET Core + Jquery實現文件斷點分片上傳 前言 該項目是基於.NET Core 和 Jquery實現的文件分片上傳,沒有經過測試,因為博主沒有那麼大的文件去測試,目前上傳2G左右的文件是沒有問題的。 使用到的技術 Redis緩存技術 Jquery ajax請求技術 為什麼要用到R ...
  • 1. 重寫和覆蓋的定義 1.1 重寫(override)的定義 在C#中,用override關鍵字來重寫一個父類中的虛方法或抽象方法。override關鍵字用於指示編譯器,我要用派生類中的一個方法,重寫基類中的同名方法。通過重寫基類中的方法,可以實現多態性。有關重寫與虛方法和抽象方法的詳細示例,可移 ...
  • 1. 多態性定義 C#中的多態性是OOP(面向對象編程)的一個基本概念,它允許一個對象在不同情況下表現出不同的行為,以增強代碼的可重用性和靈活性。 根據網上的教程,我們得知C#多態性分為兩類,靜態和動態。但實際上,C#沒有嚴格的靜態和動態多態性的分法。之所以這麼分,還是為了我們便於理解,我們沿用這個 ...
  • 1. 抽象方法與虛方法的區別 先說兩者最大的區別:抽象方法是需要子類去實現的。虛方法是已經實現了的,可以被子類覆蓋,也可以不覆蓋,取決於需求。因為抽象類無法實例化,所以抽象方法沒有辦法被調用,也就是說抽象方法永遠不可能被實現。 如果需要瞭解虛方法及抽象方法具體的定義和語句,請移步:C#多態性學習,虛 ...
  • 前段時間小編同事面試遇到了這個問題,由於同事比較菜並未很完美的完成這個問題,本文就替小編來解答一下。在C#中有多種方式類遍歷指定文件夾中的文件,本文將介紹三種方式。 一、使用Directory類的GetFiles方法: 示例代碼如下: string[] files = Directory.GetFi ...
  • PDF/A是一種ISO標準的PDF文件格式版本,是為長期保存文件而設計的。它提供了一種工具,使電子文件在長時間之後依然以一種保留其外觀的方式重現,而不管該文件是用什麼工具和系統創建、儲存或製作的。這種保留方式使PDF文件可自我持續。PDF/A通過嵌入在文檔自身內部顯示該文檔的信息(內容、顏色、字體、 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...