怎樣使用表達式樹生成動態查詢

来源:https://www.cnblogs.com/ms27946/archive/2018/01/11/how-to-use-expression-trees-to-build-dynamic-queries.html
-Advertisement-
Play Games

[翻譯]怎樣使用表達式樹生成動態查詢 在LINQ,表達式樹常用於結構化查詢,目標資源數據實現了 "IQueryable" . 例如,LINQ為關係型數據存儲查詢提供了 "IQueryable" 介面。C 編譯器將這些數據源的查詢編譯成運行時的表達式樹代碼。然後查詢提供程式可以遍歷表達式樹數據結構,並 ...


[翻譯]怎樣使用表達式樹生成動態查詢

在LINQ,表達式樹常用於結構化查詢,目標資源數據實現了 IQueryable. 例如,LINQ為關係型數據存儲查詢提供了 IQueryable 介面。C#編譯器將這些數據源的查詢編譯成運行時的表達式樹代碼。然後查詢提供程式可以遍歷表達式樹數據結構,並轉化為合適於數據源的查詢語言。

在LINQ中使用表達式樹來表示分配給 Expression 類型的Lambda表達式變數。

這節主要描述瞭如何使用表達式樹構建一個動態LINQ查詢。在編譯期,動態查詢在特殊未知的查詢的情況下是非常有用的。具體例子,一個應用程式提供了一個用戶介面,最終來允許用戶指定一個或多個謂詞來過濾數據。為了使用LINQ查詢,這種情況應用程式在運行時必須使用表達式樹來構建一個LINQ查詢。

Example

下麵這段代碼展示如何使用表達式樹去圍繞 IQueryable 數據源構造一個查詢並運行。代碼生成了一個表達式樹來表示查詢:

companies.Where(company => (company.ToLower() == "coho winery" || company.Length > 16)).OrderBy(company => company)

在命名空間 [System.Linq.Expressions](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions) 下有個工廠方法用來生成一個表達式樹來表示這個查詢。表示標準查詢運算符方法調用的表達式將引用這些方法的 Queryable 的實現。最終表達式樹被傳遞給 IQueryable 數據源的提供程式的 CreateQuery(Expression) 實現,以創建一個可執行的 IQueryable 類型的查詢。通過枚舉該查詢獲得結果。

Expression<Func<string, bool>> expr = name => name.Length > 10 && name.StartsWith("G");
Console.WriteLine(expr);

AndAlsoModifier treeModifier = new AndAlsoModifier();
Expression modifierExpr = treeModifier.Modify(expr);

Console.WriteLine(modifierExpr);

string[] companies = {"Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
        "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
        "Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
        "Blue Yonder Airlines", "Trey Research", "The Phone Company",
        "Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };
//轉化IQueryable數據源
IQueryable<string> queryableData = companies.AsQueryable();
//編寫表示謂詞參數的表達式樹
ParameterExpression pe = Expression.Parameter(typeof(string), "company");
//新建一個表達式樹來表示 'company.ToLower() == "coho winery"' 的表達式
Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
Expression right = Expression.Constant("coho winery", typeof(string));
Expression e1 = Expression.Equal(left, right);
//新建一個表達式樹來表示 'company.Length > 16' 表達式
left = Expression.Property(pe, typeof(string).GetProperty("Length"));
right = Expression.Constant(16,typeof(int));
Expression e2 = Expression.GreaterThan(left, right);
//編譯表達式樹來生成一個表示'(company.ToLower() == "coho winery" || company.Length > 16)' 的表達式
Expression predicateBody = Expression.OrElse(e1, e2);
//新建一個表達式樹來表示 'queryableData.Where(company => (company.ToLower() == "coho winery" || company.Length > 16))'
MethodCallExpression whereCallExpresstion = Expression.Call(
    typeof(Queryable),
    "Where",
    new Type[] { queryableData.ElementType },
    queryableData.Expression,
    Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { pe }));

//排序 OrderBy(company => company)
//新建一個表達式樹來表示 'whereCallExpression.OrderBy(company => company)'
MethodCallExpression orderCallExpresstion = Expression.Call(
    typeof(Queryable),
    "OrderBy",
    new Type[] { queryableData.ElementType, queryableData.ElementType },
    whereCallExpresstion,
    Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));

//新建一個可執行的查詢表達式樹
IQueryable<string> result = queryableData.Provider.CreateQuery<string>(orderCallExpresstion);

//枚舉結果
foreach (string company in companies)
    Console.WriteLine(company);

代碼中在被傳遞到 Queryable.Where 方法中,在謂詞中使用了一個固定數字。但是,你可以寫一個應用程式,來編譯在謂詞中一個依賴於用戶輸入的數字變數。你也可以根據用戶的輸入,更改查詢中調用的標準查詢操作符。

編譯代碼

  • 創建新的控制台應用程式項目。
  • 添加對 System.Core.dll 的引用(如果尚未引用)。
  • 包括 System.Linq.Expressions 命名空間。
  • 從示例中複製代碼,並將其粘貼到 Main 方法中。

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

-Advertisement-
Play Games
更多相關文章
  • 目的:只允許同級拖動。 兩個判斷: 1.原節點(假設為:S)的父級如果不等於目標節點(假設為:T)的父節點,那麼發生了跨級,即非同級移動。這個判斷很容易。 2.S、T是同一級的,但是S是移動到T下一級,這種情景下,移動過程中,S和T的父節點是一致的,不能判斷是否跨級移動,那麼怎麼辦判斷呢? 方案1: ...
  • 泛型概述 泛型是程式設計語言的一種特性。允許程式員在強類型程式設計語言中編寫代碼時定義一些可變部分,那些部分在使用前必須作出指明。各種程式設計語言和其編譯器、運行環境對泛型的支持均不一樣。將類型參數化以達到代碼復用提高軟體開發工作效率的一種數據類型。泛型類是引用類型,是堆對象,主要是引入了類型參數這 ...
  • 一. 準備工作 1. 點擊此下載支持.Net4.0的 FastReport ,安裝後並破解 2. VS2012 工具箱中,新建選項卡,添加 %安裝目錄%\Framework 4.0\FastReport.dll 選項 可在選項卡下查看到如下圖,表示整合成功 二. 相關文件介紹 1. 在 %當前用戶% ...
  • 目錄: WPF自定義Window樣式(1) WPF自定義Window樣式(2) 1. 引言 WPF是製作界面的一大利器。最近在做一個項目,用的就是WPF。既然使用了WPF了,那麼理所當然的,需要自定義窗體樣式。所使用的代碼是在網上查到的,遺憾的是,整理完畢後,再找那篇帖子卻怎麼也找不到了,僅僅在下載 ...
  • 例子: 給佈局內動態添加一個panel,給panel一個id,加內容的時候加到這個id里就可以了 html: ...
  • 參考文獻: 富文本編輯器 CKeditor 配置使用 CKEditor與CKFinder的配置(ASP.NET環境),老版本可以參考 CKEditor+CKFinder ASP版在本地電腦中的配置 有點問題 富文本文件CKEDITOR增加上傳圖片功能(.net),ckeditor上傳圖片 發現可行 ...
  • 一般在創建或者打開一個Word文檔時,如果沒有進行過特殊設置的話,系統預設的輸入語言的是英語輸入,但是為適應不同的辦公環境,我們其實是需要對文字嵌入的語言進行切換的,因此,本文將介紹如何使用免費版組件Free Spire.Doc for .NET來實現Word語言輸入。另外,針對這款組件的多種Wor ...
  • "回到目錄" Mock在單元測試里的意義 Mock測試就是在測試過程中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬的對象來創建以 便測試的測試方法。 一個鬧鐘 根據時間來進行提醒服務,如果過了 下午5點鐘 就播放音頻文件 提醒大家下班了,如果我們要利用真實的對象來測試的話就只能苦苦等到下午五 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...