基於Expression Lambda表達式樹的通用複雜動態查詢構建器——《構思篇二》已開源

来源:https://www.cnblogs.com/ls0001/archive/2023/05/27/ExpressionBuilder-3.html
-Advertisement-
Play Games

如果你有 *n* 個緩存伺服器,一個常見的負載均衡方式是使用以下的哈希方法: *伺服器索引 = 哈希(鍵) % N*,其中 *N* 是伺服器池的大小。 讓我們通過一個例子來說明這是如何工作的。如表5-1所示,我們有4台伺服器和8個字元串鍵及其哈希值。 ![image-2023052022160981 ...


接續[上篇之預告]

本篇來講講,如何根據前面設計的查詢描述器構造出可執行的表達式。正如標題所示,實現手段將採用Expression Lambda技術。

先來看看主角System.Linq.Expressions.Expression 長什麼樣,都有些什麼東西,能做什麼。 先看看它的類圖:

 

 

我們主要使用Expression這個類,它包含各種節點類型的 static工廠方法。特別是以下這些方法,對應了查詢需要用到的邏輯、比較、數學,等各種運算操作。

邏輯運算  
AndAlso(Expression, Expression) 表示And邏輯運算
OrElse(Expression, Expression) 表示Or邏輯運算
比較運算  
LessThan(Expression, Expression) 表示小於:"<"
LessThanOrEqual(Expression, Expression) 表示大於等於:“<="
GreaterThan(Expression, Expression) 表示大於:”>“
GreaterThanOrEqual(Expression, Expression) 表示大等於:”>="
Equal(Expression, Expression) 表示等於:”=“
NotEqual(Expression, Expression) 表示不等於:”!="
IsTrue(Expression) 測試表達式結果是否為“True"
IsFalse(Expression) 測試表達式結果是否為“False"
Not(Expression) 表示”Not"
數學運算  
Add(Expression, Expression) 加法
Subtract(Expression, Expression) 減法
Multiply(Expression, Expression) 乘法
Divide(Expression, Expression) 除法
Modulo(Expression, Expression) 模除
Power(Expression, Expression) 冪運算
一些操作  
Parameter(Type) 包裝一個類型為Type的參數
Call(Expression, MethodInfo, Expression, Expression) 包裝一個方法調用
Bind(MemberInfo, Expression) 包裝一個成員綁定,(屬性或欄位)
Quote(Expression) 包裝一個括弧
MakeUnary(ExpressionType, Expression, Type) 包裝一個一元運算
MakeBinary(ExpressionType, Expression, Expression) 包裝一個二元運算
TypeAs(Expression, Type) 包裝一個顯式引用或裝箱轉換,其中如果轉換失敗則提供“null”。
Coalesce(Expression, Expression, LambdaExpression) 包裝表示給定轉換函數的聚結操作。
變數、常量、欄位、屬性  
Default(Type) 包裝一個指定類型的預設值
Constant(Object, Type) 包裝一個常量
Assign(Expression, Expression) 賦值操作
Variable(Type, String) 包裝一個變數定義
Property(Expression, MethodInfo) 包裝一個屬性
Field(Expression, FieldInfo) 包裝一個欄位
PropertyOrField(Expression, String) 包裝一個指定名稱的欄位或屬性
要的就是這結果  
Lambda(Expression, ParameterExpression[]) 包裝一個委托,帶有一個參數表達式數組。

以上僅列出了一部分,它涵蓋了全部可能要使用到的函數,語句,欲詳細瞭解可以直接乘坐火箭到微軟官方網站查看。

這此函數或功能是有了,如何使用呢?來看個例子:將SQL:Table1.A > 5 and Table1.B=3,轉成(Table1)=>Table1.A > 5 && Table1.B==3;

Expression的世界里一切都是Expression。因此首先要將Table1A5B3先包裝成Expression

  • 開乾之前先談個對象
//實體類:
    public class Table
    {
        public int A;
        public int B;
    }

 

  • 然後包裝各種Expression
​
    //將Table1包裝成ParameterExpression:
    var p=Expression.Parameter(typeof(Table1),"Table1");
​
    //將5、3這兩個常量包裝成ConstantExpression:
    var num5=Expression.Constant(5,typeof(int));
    var num3=Expression.Constant(3,typeof(int));
​
    //將兩個屬性包裝成MemberExpression。
    var a=Expression.PropertyOrField(p,"A")
    var b=Expression.PropertyOrField(p,"B")
​
    //構造Table1.A>5:
    var gt=Expression.GreaterThen(a,num5); 
    //構造Table1.A=3:
    var eq=Expression.Equal(b,num3);    
    
​

 

  • 再構造兩個比較式
   //構造Table1.A>5:
   var gt=Expression.GreaterThen(a,num5); 
    //構造Table1.A=3:
    var eq=Expression.Equal(b,num3);    

 

  •  加上邏輯And將兩個比較式連接起來
    //構造Table1.A>5 && Table1.A=3
    var exp=Expression.AndAlso(gt,eq);

 

  •  結果就要出來了
//結果就獲得了:
    var lambda=Expression.Lambda()
        

 

  • 來來來,測試一下康康接果:
    /*===============來來來,測試一下:===============*/    
    var f=lambda.Compile();
    var x=f.DynamicInvoke(new Table(){A=6,B=3});
    var y = f.DynamicInvoke(new Table() { A = 2, B = 3 });
    Console.WriteLine("x:{0}\ny:{1}",x,y);
    Console.WriteLine("Lambda:{0}",lambda.ToString());          
    /*輸出:
    結果對嗎?我也不知道,我擼得這麼辛苦,先讓電腦休息一下,各位看官只要Ctrl+C,Ctrl+V就可以看到了.
    */

 

  • OK,其它各種操作,只要依葫蘆畫瓢便大功可成! 先爽一下!
  • 好,暫且爽到這裡,欲看如何把括弧弄成俄羅斯套娃,且看下回分解.
  • 隨手點個贊,讓我也爽爽,可好!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一說到創建桌面應用,就不得不提及Electron和Tauri框架。這次給大家主要分享的是基於electron最新版本整合vite4.x構建vue3桌面端應用程式。 之前也有使用vite2+vue3+electronc創建桌面端項目,不過 vue-cli-plugin-electron-builder ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、小票列印 目前市面上的小票印表機大多採用的列印指令集為ESC/POS指令,它可以使用ASCII碼、十進位、十六進位來控制列印,我們可以使用它來控制字體大小、列印排版、字體加粗、下劃線、走紙、切紙、控制錢箱等,下麵以初始化印表機為例: ...
  • apply(thisArg) apply(thisArg, argsArray) thisArg 在 func 函數運行時使用的 this 值。請註意,this 可能不是該方法看到的實際值:如果這個函數處於非嚴格模式下,則指定為 null 或 undefined 時會自動替換為指向全局對象,原始值會 ...
  • 具體的加密演算法可以可自行查詢其區別,這裡只是拋磚引玉,大部分加密方法基本都能通過改變傳入參數來實現。 C#相關類文檔: System.Security.Cryptography 命名空間 | Microsoft Learn Node JS相關文檔:Crypto | Node.js v16.20.0 ...
  • >我們是[袋鼠雲數棧 UED 團隊](http://ued.dtstack.cn/),致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。。 >本文作者:琉易 [liuxianyu.cn](https://link.juejin.cn/?target=h ...
  • # JavaScript 格式化金額 ## 一、[使用 `Intl.NumberFormat` 構造函數](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberForm ...
  • > 隨著人工智慧技術的不斷發展,阿裡體育等IT大廠,推出的“樂動力”、“天天跳繩”AI運動APP,讓**雲上運動會、線上運動會、健身打卡、AI體育指導**等概念空前火熱。那麼,能否將這些在APP成功應用的場景搬上小程式,分享這些概念的紅利呢?本系列文章就帶您一步一步從零開始開發一個AI運動小程式,本 ...
  • 前端構建的提速是一項比較複雜且細節的工程, 目前產品上在持續跟蹤構建慢的應用, 努力優化編譯速度, 但前端本身擁有一個比較自由的技術環境, 沒有統一的構建工具與流程, 另外語言本身的執行效率、單線程的構建也不好讓編譯機發揮其最大能力, 所以目前全局的通用優化手段還是會比較局限, 還是依賴項目自身的優... ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...