初識Linq to Entity

来源:http://www.cnblogs.com/zhaokunbokeyuan256/archive/2017/06/20/7055756.html
-Advertisement-
Play Games

背景:C# .Net MVC ,以及已經開發了近1年半的我,做了好久但是對於這個技術沒有總結,這是一個機會,寫寫我理解的東西吧。--以下內容參考了別人的文章 技術介紹: LINQ(Language Integrated Query,語言集成查詢)是一組用於C#和VB.NET語言的擴展,它允許編寫C# ...


背景:C# .Net MVC ,以及已經開發了近1年半的我,做了好久但是對於這個技術沒有總結,這是一個機會,寫寫我理解的東西吧。--以下內容參考了別人的文章


技術介紹:

LINQ(Language Integrated Query,語言集成查詢)是一組用於C#和VB.NET語言的擴展,它允許編寫C#或者VB.net代碼,以與查詢資料庫相同的方式操作記憶體數據。LINQ提供了豐富的類似SQL的查詢語法,功能強大且容易上手。下圖彙總展示了LINQ技術的官方實現集合:

正如上圖所示,LINQ to Entities 是LINQ技術在實體對象模型中的一種實現,它與LINQ to SQL以及LINQ to DataSets一起構成了LINQ to ADO.Net。LINQ to Entities可以生成eSQL,並支持使用LINQ語法對實體框架服務層進行查詢。下圖展示了LINQ to Entities消費實體數據模型的技術細節:


 

概念邏輯:

在開始瞭解LINQ to Entities之前,需要先對.NET Framework 3.5版本後對C#語言的幾個擴展特性做一些闡釋,這有助於我們更容易、更深刻的理解LINQ to Entities技術的原理與實現。

一、隱式實例化局部變數

.NET Framework 3.5後,實例化局部變數語法有了新的選擇:使用“var”關鍵字隱式類型化:

var user = new User();

隱式類型化語法與JavaScript語言里聲明變數的語法類似,它可以一定程度上簡化實例化局部變數的語法。但如果隱式實例化的作用僅限於此,那本文不會專門提及。隱式類型化更重要的用途是用於匿名類型的實例化。

需要提醒註意的是,只有局部變數實例化允許使用隱式實例化語法。這表示私有變數實例化無法享受該福利;同時,僅聲明變數或實例化對象為null也是不允許使用隱式實例化語法的。

二、對象初始化

對象初始化指在實例化對象時,即可對對象的屬性進行賦值:

1 var user = new User()
2 {
3     ID = Guid.NewGuid(),
4     Account = "Apollo"
5 };

三、匿名類型

LINQ to Entities的Select可以將實體類型投影為匿名類型,所以有必要對匿名類型作簡單介紹。匿名類型指的是不顯示聲明類型的細節,而是根據上下文環境需要,臨時聲明滿足需要的類型。由於該類型是臨時需要的,所以不必為之命名。匿名類型的聲明語法如下:

var user = new { ID = Guid.NewGuid(), Name = "Apollo" };

四、擴展方法

擴展方法是微軟為擴展已有框架而創造的一個語法糖,.NET Framework 3.5就是通過很多擴展方法實現了對.NET Framework 2.0的升級擴展的。擴展方法很神奇,被擴展的對象可以不知道擴展方法的存在,就能在行為上得到擴展。擴展方法也很蹩腳,如果使用者不知情,很可能不知道對象具有擴展行為;抑或知道有擴展方法,但是不知道要引用哪個擴展庫以使其支持擴展的行為。擴展方法的語法如下:

1 public static class UserExt
2 {
3     public static void Drink(this User user, object water)
4     {
5         …
6     }
7 }

五、Lambda表達式

Lambda表達式是由委托以及匿名方法發展而來的,它可將表達式或代碼塊(匿名方法)賦給一個變數,從而以最少量的輸入實現編碼目的。Lambda表達式一般配合IEnumerable<T>的靜態擴展方法使用,完成對象集合的快捷查詢操作。Lambda表達式的語法如下:

var user = db.Users.FirstOrDefault(o => o.Account == "Apollo");

六、標準查詢操作符

System.Linq.Enumerable靜態類聲明瞭一套標準查詢操作符(Standard Query Operators,SQO)方法集合。標準查詢操作符的語法和標準SQL很相似,這不是偶然,而是微軟有意為之,以使熟悉SQL的程式員們更容易上手。標準查詢操作符的基本語法如下:

1 using (var db = new EntityContext())
2 {
3     var roles = from o in db.Users
4                where o.Account == "Apollo"
5                select o.Roles;
6     …
7 }

標準查詢操作符和Lambda表達式的關係非常密切。編譯器會將上訴表達式轉化為下列以Lambda表達式為參數的顯式擴展方法調用序列:

1 using (var db = new EntityContext())
2 {
3     var roles = db.Users.Where(o => o.Account == "Apollo").Select(o => o.Roles);
4 }

 

標準查詢操作符

接下來,將針對數據查詢操作中常用的條件查詢、投影、分區、排序、分組、集合、元素、量詞和聚集等標準查詢操作符進行分類介紹。

一、條件操作符

條件操作符Where類似於SQL中的WHERE子句,用於實現條件查詢。下列擴展方法表達式查詢滿足條件“角色不為空”的用戶集合:

var user = db.Users.Where(o => o.Roles != null);

對應的標準查詢操作符表達式為:

1 var users = from o in db.Users
2             where o.Roles != null
3             select o;

二、投影操作符

投影操作符Select類似於SQL中的SELECT子句,將對象投影為一個匿名類型實例,用於控制指定查詢迭代器顯示或者處理的對象屬性。另外,需要註意的是,擴展方法表達式中的Select操作符並非必須的,省略模式下,會返回完整的被投影對象。下列擴展方法表達式將用戶的帳號和密碼信息投影為一個匿名類型:

var users = db.Users.Select(o => new { o.Account, o.Password });

對應的標準查詢操作符表達式為:

1 var users = from o in db.Users
2             select new { o.Account, o.Password };

三、分區操作符

分區操作符實現對象的分區操作。其中,Take操作符類似於SQL中的TOP操作符,下列擴展方法表達式返回前5個用戶對象:

var users = db.Users.OrderBy(o => o.Roles.Count).Take(5);

Skip操作符用於跳過指定個數對象並返回序列中的剩餘對象,下列擴展方法表達式返回除前10個用戶外的剩餘用戶:

var users = db.Users.OrderBy(o => o.Roles.Count).Skip(10);

TakeWhile操作符用於返回條件表達式值為真時的相鄰元素集合,下列擴展方法表達式返回第一個擁有3個角色的用戶之前的所有用戶集合:

var users = db.Users.OrderBy(o => o.Roles.Count).TakeWhile(o => o.Roles.Count == 3);

SkipWhile操作符用於跳過條件表達式值為真時的元素,並返回剩下的元素集合,下列擴展方法表達式返回第一個擁有3個角色的用戶之後的所有用戶集合:

var users = db.Users.OrderBy(o => o.Roles.Count).SkipWhile(o => o.Roles == 3);

四、排序操作符

排序操作符實現對象的排序功能,包括OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse五個操作符。其中OrderBy操作符實現對象的升序排列,相當於SQL中的ORDER BY ASC子句,下列擴展方法表達式實現用戶按擁有的角色數進行升序排列:

var users = db.Users.OrderBy(o => o.Roles.Count);

對應的標準查詢操作符表達式為:

1 var users = from o in db.Users
2             orderby o.Roles.Count
3             select o;

OrderByDescending操作符實現對象的降序排列,相當於SQL中的ORDER BY DESC子句,下列擴展方法表達式實現用戶按擁有的角色數進行降序排列:

var users = db.Users.OrderByDescending(o => o.Roles.Count);

對應的標準查詢操作符表達式為:

1 var users = from o in db.Users
2             orderby o.Roles.Count descending
3             select o;

ThenBy、ThenByDescending和Reverse操作符只能針對IOrderedEnumerable介面對象使用,所以一般緊跟在OrderBy/OrderByDesending操作符方法後使用。ThenBy操作符由編譯器翻譯為對OrderBy操作符的再次調用;ThenByDescending操作符由編譯器翻譯為對OrderByDescending操作符的再次調用;Reverse操作符實現對象的排序反向。這裡不再一一舉例。

五、分組操作符

分組操作符GroupBy類似於SQL中的GROUP BY子句,實現對象的分組操作。下列擴展方法表達式實現用戶對象按擁有的角色數量進行分組:

var users = db.Users.GroupBy(o => o.Roles.Count);

對應的標準查詢操作符表達式為:

1 var users = from o in db.Users
2             group o by o.Roles.Count into g
3             select new { RoleCount = g.Key, Group = g };

六、集合操作符

集合操作符包括Distinct、Union、intersect和Except四個操作符,除Distinct外,其他三個操作符都可將兩個序列組合成一個序列。Distinct操作符類似於SQL中的DISTINCT關鍵字,用於刪除序列中具有重覆值的對象。下列擴展方法表達式實現將用戶角色中的重覆角色刪除功能:

var roles = user.Roles.Distinct();

Union操作符類似於SQL中的UNION關鍵字,用於求具有同樣結構的兩個序列的並集。下列擴展方法表達式實現將用戶1和用戶2所擁有的角色組合成一個角色集合,併排除其中重覆的角色:

var roles = user1.Roles.Union(user2.Roles);

Intersect操作符類似於SQL中的INTERSECT關鍵字,用於求具有同樣結構的兩個序列的交集。下列擴展方法表達式返回用戶1和用戶2都具有的角色集合:

var roles = user1.Roles.Intersect(user2.Roles);

Except操作符類似於SQL中的EXCEPT關鍵字,用於返回第一個序列中有、但第二個序列中沒有的對象集合。下列擴展方法表達式返回用戶1擁有,而用戶2沒有的角色集合:

var roles = user1.Roles.Except(user2.Roles);

七、元素操作符

元素操作符包括兩組操作符,分別是用於從一個IEnumerable<T>序列中返回滿足條件的單個對象或無滿足條件對象時拋異常的First、Last和Single操作符,以及返回滿足條件的單個對象或無滿足條件對象時返回空對象的FirstOrDefault、LastOrDefault和SingleOrDefault操作符。其中First和FirstOrDefault操作符用於返回第一個滿足條件的對象。下列擴展方法表達式返回第一個擁有三個角色的用戶:

var user = db.Users.FirstOrDefault(o => o.Roles.Count == 3);

Last和LastOrDefault操作符用於返回最後一個滿足條件的對象。下列擴展方法表達式返回最後一個擁有三個角色的用戶:

var user = db.Users.LastOrDefault(o => o.Roles.Count == 3);

Single和SingleOrDefault操作符用於返回滿足條件的序列中的唯一元素,如果序列中包含不止一個元素,將會拋異常。下列擴展方法表達式返回帳號為“Apollo”的唯一用戶,如果有多個用戶帳號都為“Apollo”,則拋異常:

var user = db.Users.SingleOrDefault(o => o.Account == "Apollo");

八、量詞操作符

量詞操作符包括 Any、All和Contains三個操作符,用於檢查序列中是否有一些對象或所有對象滿足條件。其中,Any操作符用於檢查序列中是否有任何一個對象滿足條件。下列擴展方法表達式當有任何一個用戶擁有三個角色時返回真,否則返回假:

var result = db.Users.Any(o => o.Roles.Count == 3);

All操作符用於檢查序列中是否所有對象均滿足條件。下列擴展方法表達式當所有用戶均擁有三個角色時返回真,否則返回假:

var result = db.Users.All(o => o.Roles.Count == 3);

Contains操作符用於檢查序列中是否包含指定的對象。下列擴展方法表達式當集合中包含用戶1則返回真,否則返回假:

var result = db.Users.Where(o => o.Roles.Count == 3).Contains(user1);

九、聚集操作符

聚集操作符包括Count、Min、Max、Sum和Average等多個操作符,用於對對象集合進行統計計算。其中,Count操作符類似於SQL中的COUNT關鍵字,用於計算序列中滿足條件的對象個數。下列擴展方法表達式返回擁有3個角色的用戶數量:

var result = db.Users.Count(o => o.Roles.Count == 3);

Min操作符類似於SQL中的MIN關鍵字,用於返回按條件計算的最小值。下列擴展方法表達式返回擁有最少角色數量的用戶所擁有的角色數量:

var result = db.Users.Min(o => o.Roles.Count);

Max操作符類似於SQL中的MAX關鍵字,用於返回按條件計算的最大值。下列擴展方法表達式返回擁有角色數量最多的用戶所擁有的角色數量:

var result = db.Users.Max(o => o.Roles.Count);

Sum操作符類似於SQL中的SUM關鍵字,用於返回按條件計算的總數。下列擴展方法表達式返回已賦予用戶的所有角色總數:

var result = db.Users.Sum(o => o.Roles.Count);

Average操作符類似於SQL中的AVERAGE關鍵字,用於返回按條件計算的平均值。下列擴展方法表達式,用於返回用戶所擁有的角色平均數:

var result = db.Users.Average(o => o.Roles.Count);

 

總結

本文首先給出了LINQ技術的官方實現集合,以及LINQ to Entities實現的技術細節;然後概要介紹了與LINQ to Entities相關的幾個基本概念;最後對LINQ to Entities常用的標準查詢操作符的使用進行了分類介紹,從中也可以看出LINQ to Entities和SQL的功能基本是一一對應的。

文章寫得比較通俗易懂也相對全面,更多的是給自己做一些記錄,方便自己查看。

 


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

-Advertisement-
Play Games
更多相關文章
  • 1.安裝好jdk。 2.打開終端。 3.sudo到root帳戶,輸入 vi /etc/profile ,打開全局配置文件。 4.在profile中添加如下配置 JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/ ...
  • 在編程或是整理知識的時候一直苦於沒有一款可以幫助理清思路的工具。 在網上苦尋良久,終於找到了一款可心可意的小軟體 —— Graphviz。 折騰了一番,終於可以湊合著用了。 現將折騰的成果記錄於此以作備忘,當然如果能夠拋磚引玉那就再好不過了。 因為本人主要使用 Windows 以下將用 Window ...
  • ubuntn預設下載路徑的源是國外的下載很慢換成國內的下載路徑會好很多 在ubuntu應用搜索框(左上腳那個)中輸入software 1.software&Updates 應用點擊software 2.在彈出的界面中的download中選擇other 3.在之後彈出的框中選到china 4.在裡面選 ...
  • Shell腳本,就是利用Shell的命令解釋的功能,對一個純文本的文件進行解析,然後執行這些功能,也可以說Shell腳本就是一系列命令的集合。Shell可以直接使用在win/Unix/Linux上面,並且可以調用大量系統內部的功能來解釋執行程式,如果熟練掌握Shell腳本,可以讓我們操作電腦變得更 ...
  • awk [-field-separator] 'commands' input-file(s) ...
  • 在.Net框架中,如果您查看所有類型的的基類:System.Object類,將找到如下4個與相等判斷的方法: static Equals() virtual Equals() static ReferenceEquals() virtual GetHashCode() 除此之外,Microsoft已 ...
  • 配置的本質就是字元串的鍵值對,但是對於面向對象語言來說,能使用強類型的配置是何等的爽哉! 目錄 1. ASP.NET Core 配置系統 2. 強類型的 Options 3. Configure 方法 4. 源碼解析 ASP.NET Core 配置系統 在ASP.NET 4.X中,通常將配置存儲在 ...
  • C#編寫簡易的學生成績查詢 什麼是學生成績查詢系統? 使用C#語言編寫的一個可安裝的簡單CS系統,實現了用戶登錄,學生信息添加,成績修改,刪除,查詢等功能 開發環境 開發環境 visual studio2010(新版本2015,2017也可) visual studio2010(sql2008資料庫 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...