日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET:使用 LinqSharp 简化复杂查询

發布時間:2023/12/4 asp.net 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET:使用 LinqSharp 简化复杂查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LinqSharp?是個開源?LINQ?擴展庫,它允許您編寫簡單代碼來生成復雜查詢,包括查詢擴展和動態查詢生成。

LinqSharp.EFCore?是對?EntityFramework?的增強庫,提供更多數據注解、數據庫函數及自定義儲存規則等。

https://github.com/zmjack/LinqSharp

由于內容較多,將分篇介紹公開內容、原理及案例分享:

  • LinqSharp:簡化復雜查詢

  • LinqSharp:動態構建 LINQ 查詢

  • LinqSharp.EFCore:表設計數據注解

  • LinqSharp.EFCore:字段標準化數據注解

  • LinqSharp.EFCore:函數映射

  • LinqSharp.EFCore:列式存儲代理

  • LinqSharp.EFCore:關聯計算與審計

  • 本文多數示例,提供在線運行測試(.NET Fiddle)。


    LinqSharp?為?LINQ?提供了以下增強(“內存查詢”或“SQL生成”):

    • 默認返回方法
      MinOrDefault:提供默認返回的?Min?方法;
      MaxOrDefault:提供默認返回的?Max?方法;
      AverageOrDefault:提供默認返回的?Average?方法。

    • 查詢值最小或最大的記錄
      WhereMin:查詢指定字段最小的記錄;
      WhereMax:查詢指定字段最大的記錄。

    • 數據搜索
      Search:在指定字段或鏈接表字段中模糊或精確查詢數據;

    • 分頁查詢
      SelectPage:查詢結果分頁或執行分頁查詢。

    • 序列排序
      OrderByCase / ThenByCase:按指定字符串序列排序。

    • 構建動態查詢
      XWhere:構建動態查詢。

    以下方法僅提供于內存查詢:

    • 按組元素數量分組
      GroupByCount:按分組記錄元素數量分組。

    • 樹結構查詢
      SelectMore:按樹結構遍歷,選擇“所有樹節點中滿足條件的節點”;
      SelectUntil:按樹結構遍歷,直到在每個子路徑中找到滿足條件的節點,選擇該節點;
      SelectWhile:按樹結構遍歷,選擇“所有子路徑中連續滿足條件的路徑節點”。


    示例庫 Northwnd

    Northwnd?是?SQL Server?早期附帶的示例數據庫,該數據庫描述“公司銷售產品網”簡單案例場景。包括“雇員(Employees)”“產品訂單(Orders)”“供應商(Suppliers)”的關系網絡。

    本文示例使用的是它的?Sqlite?版本(Code First):

    https://github.com/zmjack/Northwnd

    通過?NuGet?安裝:

    dotnet add package Northwnd dotnet add package LinqSharp dotnet add package LinqSharp.EFCore

    簡單使用:

    using (var sqlite = NorthwndContext.UseSqliteResource()) {... }

    輸出 SQL

    “輸出 SQL”是研究“SQL 生成”的基礎,使用?LinqSharp.EFCore?中的?ToSql?方法:

    (在線示例:ToSql | C# Online Compiler)

    using (var sqlite = NorthwndContext.UseSqliteResource()) {var query = sqlite.Regions.Where(x => x.RegionDescription == "Northern");var sql = query.ToSql(); }

    生成 SQL:

    SELECT "r"."RegionID", "r"."RegionDescription" FROM "Regions" AS "r" WHERE "r"."RegionDescription" = 'Northern';

    注1:由于不同版本的?EntityFrameworkCore?的?SQL?生成器設計不同,因此,生成 SQL 可能會存在差異。(EntityFrameworkCore 5.0?公開了?ToQueryString?來支持這項功能)。

    注2:LinqSharp.EFCore?最新版本不兼容所有?EntityFrameworkCore,需使用“大版本號”與?EntityFrameworkCore?一致的發行庫(例如,2.2.x,3.0.x,3.1.x)。

    默認返回方法擴展

    • MinOrDefault:原函數?Min?的不拋異常版本,異常返回默認值;

    • MaxOrDefault:原函數?Max?的不拋異常版本,異常返回默認值;

    • AverageOrDefault:原函數?Average?的不拋異常版本,異常返回默認值。

    (在線示例:MinOrDefault | C# Online Compiler)

    // throw 'Sequence contains no elements' new int[0].Min();new int[0].MinOrDefault(); // 0 new int[0].MinOrDefault(-1); // -1

    查詢值最小或最大的記錄

    • WhereMin:查詢指定字段最小的記錄;

    • WhereMax:查詢指定字段最大的記錄。

    WhereMin?和?WhereMax?會進行兩次查詢:

  • 查詢指定字段的“最小值”或“最大值”;

  • 查詢指定字段“最小值”或“最大值”的記錄。

  • 例如,查詢員工(Empolyees)表中年齡最小的員工:

    (在線示例:WhereMax | C# Online Compiler)

    var query = sqlite.Employees.WhereMax(x => x.BirthDate); var result = query.Select(x => new {x.EmployeeID,x.FirstName,x.BirthDate, }).ToArray();

    生成 SQL:

    /* Step 1 */ SELECT MIN("e"."BirthDate") FROM "Employees" AS "e";/* Step 2 */ SELECT * FROM "Employees" AS "e" WHERE "e"."BirthDate" = '1966-01-27 00:00:00';

    運行結果:

    數據搜索

    • Search:返回“從指定字段或外鍵表字段中進行模糊或精確查詢”的查詢結果。

    Search?函數提供了四種搜索模式(SearchOption):

    • Contains(默認):任何指定字段中“包含”搜索字符串;

    • NotContains:所有指定字段中都“不包含”搜索字符串;

    • Equals:搜索字符串與某指定字段“相等”;

    • NotEquals:搜索字符串“不在”任何指定字段中。

    例如,查詢雇員(Employees)表中地址(Address)或城市(City)包含字母?m?的雇員:

    (在線示例:Search | C# Online Compiler)

    var query = sqlite.Employees.Search("m", e => new{e.Address,e.City,}); var result = query.Select(x => new {x.EmployeeID,x.Address,x.City, }).ToArray();

    生成 SQL:

    SELECT * FROM "Employees" AS "e" WHERE (('m' = '') OR (instr("e"."Address", 'm') > 0)) OR (('m' = '') OR (instr("e"."City", 'm') > 0));

    運行結果:

    Search?函數同樣提供了外鏈表的查詢(主表或從表查詢)。

    例如,查詢供應商(Suppliers)表中供應任何種類豆腐(Tofu)的供應商:

    (在線示例:Search (Details) | C# Online Compiler)

    var query = sqlite.Suppliers.Include(x => x.Products).Search("Tofu", s => new{ProductNames = s.Products.Select(x => x.ProductName),});var result = query.Select(x => new {x.SupplierID,x.CompanyName,Products = string.Join(", ", x.Products.Select(p => p.ProductName)), }).ToArray();

    生成 SQL:

    SELECT * FROM "Suppliers" AS "s" LEFT JOIN "Products" AS "p" ON "s"."SupplierID" = "p"."SupplierID" WHERE EXISTS (SELECT 1FROM "Products" AS "p0"WHERE ("s"."SupplierID" = "p0"."SupplierID") AND (('Tofu' = '') OR (instr("p0"."ProductName", 'Tofu') > 0))) ORDER BY "s"."SupplierID", "p"."ProductID";

    運行結果:

    分頁查詢

    • SelectPage:查詢結果分頁或執行分頁查詢。(分頁參數從第?1?頁開始)

    例如,查詢雇員(Employees)表,按每頁?2?條記錄分頁,選擇第?3?頁的記錄返回:

    (在線示例:SelectPage | C# Online Compiler)

    var query = sqlite.Employees.SelectPage(pageNumber: 3, pageSize: 2); var result = query.Select(x => new {x.EmployeeID,x.Address,x.City, }).ToArray();

    生成 SQL:

    SELECT * FROM "Employees" AS "e" ORDER BY (SELECT 1) LIMIT 2 OFFSET 4;

    運行結果:

    序列排序

    • OrderByCase / ThenByCase:按指定字符串序列排序。

    例如,查詢地區(Regions)表,將結果按?N / E / W / S?的地區序列排序返回:

    (在線示例:OrderByCase | C# Online Compiler)

    var query = sqlite.Regions.OrderByCase(x => x.RegionDescription, new[]{"Northern","Eastern","Western","Southern",}); var result = query.Select(x => new {x.RegionID,x.RegionDescription, });

    執行 SQL:

    SELECT * FROM "Regions" AS "r" ORDER BY CASEWHEN "r"."RegionDescription" = 'Northern' THEN 0ELSE CASEWHEN "r"."RegionDescription" = 'Eastern' THEN 1ELSE CASEWHEN "r"."RegionDescription" = 'Western' THEN 2ELSE CASEWHEN "r"."RegionDescription" = 'Southern' THEN 3ELSE 4ENDENDEND END;

    運行結果:


    按組元素數量分組

    數量分組函數?GroupByCount?用于根據指定每組記錄數量(每組最多允許?n?條記錄)進行特殊分組。

    例如,將如下指定字符串按每行?16?個字符分成多行:

    var s = "0123456789ABCDEF0123456789ABCDEF".GroupByCount(16).Select(g => new string(g.ToArray())); 0123456789ABCDEF
    0123456789ABCDEF

    樹結構查詢

    • SelectMore:按樹結構遍歷,選擇“樹節點中?所有?滿足條件的?節點”;

    • SelectUntil:按樹結構遍歷,直到?在每個子路徑中找到滿足條件的節點,選擇?該節點;

    • SelectWhile:按樹結構遍歷,選擇“所有子路徑?中連續滿足條件的?路徑節點”。

    例如,雇員(Employees)表按照?EmployeeID?和?ReportsTo?定義結構如下:

    SelectMore

    按樹結構遍歷,選擇“樹節點中?所有?滿足條件的?節點”。

    例如,查詢由?2?號雇員?Andrew?領導的所有成員(2, 1, 3, 4, 5, 6, 7, 9, 8):

    方法:使用?SelectMore?從根節點查找即可。

    (在線示例:SelectMore | C# Online Compiler)

    var employees = sqlite.Employees.Include(x => x.Superordinate).Include(x => x.Subordinates).ToArray(); var query = employees.Where(x => x.EmployeeID == 2).SelectMore(x => x.Subordinates);var result = query.Select(x => new {x.EmployeeID,x.FirstName,x.ReportsTo,ReportsTo_ = x.Superordinate?.FirstName, });

    運行結果:

    SelectUntil

    按樹結構遍歷,直到?在每個子路徑中找到滿足條件的節點,選擇?該節點。

    例如,查詢由?2?號雇員?Andrew?領導的所有基層員工(葉節點,1, 3, 6, 7, 9, 8):

    方法:使用?SelectUntil?從根節點查找,直到節點?Subordinates?為空。

    (在線示例:SelectUntil | C# Online Compiler)

    var employees = sqlite.Employees.Include(x => x.Superordinate).Include(x => x.Subordinates).ToArray(); var query = employees.Where(x => x.EmployeeID == 2).SelectUntil(x => x.Subordinates, x => !x.Subordinates.Any());var result = query.Select(x => new {x.EmployeeID,x.FirstName,x.ReportsTo,ReportsTo_ = x.Superordinate?.FirstName, });

    運行結果:

    SelectWhile

    按樹結構遍歷,選擇“所有子路徑?中連續滿足條件的?路徑節點”。

    例如,查詢由?2?號雇員?Andrew?領導的所有非基層員工(非葉節點,2, 5):

    方法:使用?SelectWhile?從根節點查找路徑,直到節點?Subordinates?為空。

    (在線示例:SelectWhile | C# Online Compiler)

    var employees = sqlite.Employees.Include(x => x.Superordinate).Include(x => x.Subordinates).ToArray(); var query = employees.Where(x => x.EmployeeID == 2).SelectWhile(x => x.Subordinates, x => x.Subordinates.Any());var result = query.Select(x => new {x.EmployeeID,x.FirstName,Subordinates = string.Join(", ", x.Subordinates.SelectMore(s => s.Subordinates).Select(s => s.FirstName)), });

    運行結果:


    下篇文章將介紹如何使用?LinqSharp?“動態生成查詢”,敬請關注。

    總結

    以上是生活随笔為你收集整理的.NET:使用 LinqSharp 简化复杂查询的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。