網(wǎng)站首頁 編程語言 正文
一、LINQ的體系結(jié)構(gòu)
語言集成查詢 (LINQ) (C#) | Microsoft 官方文檔
LINQ總共包括五個(gè)部分:
? |
程序集 |
命名空間 |
描述 |
---|---|---|---|
LINQ to Objects |
System.Core.dll |
System.Linq |
提供對(duì)內(nèi)存中集合操作的支持 |
LINQ to XML |
System.Xml.Linq.dll |
System.Xml.Linq |
提供對(duì)XML數(shù)據(jù)源的操作的支持 |
LINQ to SQL |
System.Data.Linq.dll |
System.Data.Linq |
提供對(duì)Sql Server數(shù)據(jù)源操作的支持。(微軟已宣布不再更新,推薦使用LINQ to Entities) |
LINQ to DataSet |
System.Data.DataSetExtensions.dll |
System.Data |
提供對(duì)離線數(shù)據(jù)集DataTable操作的支持。 |
LINQ to Entities |
System.Core.dll 和System.Data.Entity.dll |
System.Linq和System.Data.Objects |
LINQ to Entities 是 Entity Framework 的一部分并且取代LINQ to SQL 作為在數(shù)據(jù)庫上使用 LINQ 的標(biāo)準(zhǔn)機(jī)制。 |
目前,除了以下的,還可以下載其他第三方提供程序,例如LINQ to JSON、LINQ to MySQL、LINQ to Amazon、LINQ to Flickr和LINQ to SharePoint。無論使用什么數(shù)據(jù)源,都可以通過LINQ使用相同的API進(jìn)行操作。
二、 LINQ的語法
1、Query查詢表達(dá)式語法
LINQ查詢表達(dá)式以from子句開頭,以select子句或group子句結(jié)束。
在兩個(gè)子句之間,可以使用where、orderby、join、let等查詢操作符。
關(guān)鍵字有: from 、where 、select 、group 、into 、orderby、join、let、in、on、equals、by、ascending、descending等。
- from…in…:指定要查找的數(shù)據(jù)源以及范圍變量,多個(gè)from子句則表示從多個(gè)數(shù)據(jù)源查找數(shù)據(jù)。注意:c#編譯器會(huì)把“復(fù)合from子句”的查詢表達(dá)式轉(zhuǎn)換為SelectMany()擴(kuò)展方法。
- join…in…on…equals…:指定多個(gè)數(shù)據(jù)源的關(guān)聯(lián)方式
- let:引入用于存儲(chǔ)查詢表達(dá)式中子表達(dá)式結(jié)果的范圍變量。通常能達(dá)到層次感會(huì)更好,使代碼更易于閱讀。
- orderby、descending:指定元素的排序字段和排序方式。當(dāng)有多個(gè)排序字段時(shí),由字段順序確定主次關(guān)系,可指定升序和降序兩種排序方式
- where:指定元素的篩選條件。多個(gè)where子句則表示了并列條件,必須全部都滿足才能入選。每個(gè)where子句可以使用謂詞&&、||連接多個(gè)條件表達(dá)式。
- group:指定元素的分組字段。
- select:指定查詢要返回的目標(biāo)數(shù)據(jù),可以指定任何類型,甚至是匿名類型。(目前通常被指定為匿名類型)
-
into:提供一個(gè)臨時(shí)的標(biāo)識(shí)符。該標(biāo)識(shí)可以引用join、group和select子句的結(jié)果。?
1) 直接出現(xiàn)在join子句之后的into關(guān)鍵字會(huì)被翻譯為GroupJoin。(into之前的查詢變量可以繼續(xù)使用)?
2) select或group子句之后的into它會(huì)重新開始一個(gè)查詢,讓我們可以繼續(xù)引入where, orderby和select子句,它是對(duì)分步構(gòu)建查詢表達(dá)式的一種簡(jiǎn)寫方式。(into之前的查詢變量都不可再使用)
編譯器會(huì)在程序編譯時(shí)轉(zhuǎn)換LINQ查詢,以調(diào)用相應(yīng)的擴(kuò)展方法。
下面是一個(gè)簡(jiǎn)單的示例,查詢一個(gè)int數(shù)組中小于5的元素,并按照從小到大的順序排列:
int[] arr = new int[] { 1, 4, 2, 6, 7, 9, 5, 1, 2, 4 };
var query = from r in arr
where r < 5
orderby r
select r;
foreach (var item in query)
{
Console.WriteLine(item);
}
Console.ReadLine();
Linq語句最終被轉(zhuǎn)換為調(diào)用IEnumerable<T>的擴(kuò)展方法,在System.Linq.Enumerable靜態(tài)類中定義了N多擴(kuò)展。所以只要繼承與IEnumerable的類都支持Linq查詢 。
2、Lambda語法
標(biāo)準(zhǔn)查詢操作符
Enumberable 類定義的標(biāo)準(zhǔn)查詢操作符。
-
篩選操作符:定義返回元素的條件。?
Where:使用謂詞,返回符合條件的元素。?
OfType<TResult>:返回符合類型的元素。? -
投射操作符:用于把對(duì)象轉(zhuǎn)換為另一個(gè)類型的新對(duì)象。?
Select?:定義根據(jù)選擇器函數(shù)選擇結(jié)果值的投射。?
SelectMany:定義根據(jù)選擇器函數(shù)選擇結(jié)果值的投射。? -
排序操作符:改變返回的元素的順序。?
Orderby:?升序排序。?
OrderBydescending:? 降序排序。?
ThenBy?和?ThenByDescending:?二次排序。?
Reverse:?反轉(zhuǎn)集合元素。? -
連接操作符:用于合并不直接相關(guān)的集合。?
Join:?? 根據(jù)鍵選擇器函數(shù)連接兩個(gè)集合。?
GroupJoin:?? 連接兩個(gè)集合,并分組。? -
組合操作符:把數(shù)據(jù)放在組中。?
GroupBy? : 組合公共鍵的元素。?
ToLookup:創(chuàng)建一個(gè)一對(duì)多字典,組合元素。? -
限定(量詞)操作符:元素滿足指定的條件。?
Any?:部分滿足謂詞函數(shù)的元素。?
All?: 所有元素是否都滿足謂詞函數(shù)。?
Contains:?? 檢查某個(gè)元素是否在集合中。? -
分區(qū)操作符:返回集合的子集。?
Take: 從集合提取元素個(gè)數(shù)。?
Skip?:跳過指定的元素個(gè)數(shù),提取其他元素。?
TakeWhile?:提取條件為真的元素。?
SkipWhile:提取條件為真的元素。? -
Set操作符:返回一個(gè)集合。?
Distinct?:(去重)刪除重復(fù)的元素。?
Union: (并集)返回集合中唯一元素。?
Intersect:(交集)返回兩個(gè)集合都有的元素。?
Except?: (差集)只出現(xiàn)在一個(gè)集合中的元素。?
Zip: 兩個(gè)集合合并為一個(gè)元素。? -
元素操作符:返回一個(gè)元素。?
First:返回第一個(gè)滿足條件的元素。?
FirstOrDefault:類似First,如果未找到,返回類型的默認(rèn)值。?
Last:返回最后一個(gè)滿足條件的元素。?
LastOrDefault:類似Last,如果未找到,返回類型的默認(rèn)值。?
ElementAt:返回元素的位置。?
ElementAtOrDefault:指定索引(超出索引,取默認(rèn)值)?
Single:返回一個(gè)滿足條件的元素。如果有多個(gè)元素都滿足條件,就拋出一個(gè)異常。?
SingleOrDefault:類似Single,如果非唯一或者找不到,返回類型的默認(rèn)值。? -
聚合操作符:計(jì)算集合值。?
Sum:?總和。?
Count:? 所有元素個(gè)數(shù)。?
LongCount:計(jì)數(shù)(大型集合)?
Min:? 最小元素。?
Max?: 最大元素。?
Average:?平均值。?
Aggregate:? 根據(jù)輸入的表達(dá)式獲取聚合值。? -
轉(zhuǎn)換操作符:?
ToArray:變成數(shù)組?
AsEnumerable:變成IEnumeralbe<T>?
AsQueryable:變成IQueryable?
ToList:變成List<T>?
ToDictionary:變成字典?
Cast<TResult>?:轉(zhuǎn)換?
ToLookup:變一對(duì)多字典Lookup<Tkey,TElement>? -
生成操作符:?
Empty?:空集合。?
DefaultIfEmpty:默認(rèn)值集合?
Range:返回一系列數(shù)字。?
Repeat: 返回始終重復(fù)一直的集合。? -
等值操作?
SequenceEqual:成對(duì)比較? -
串聯(lián)操作?
Concat:串聯(lián)
3、擴(kuò)展方法存在對(duì)應(yīng)的查詢表達(dá)式關(guān)鍵字:
- Where:where
- Select:select
- SelectMany:使用多個(gè) from 子句
- OrderBy:orderby
- ThenBy:orderby …, …
- OrderByDescending:orderby … descending
- ThenByDescending:orderby …, … descending
- GroupBy:group … by 或 group … by … into …
- Join:join … in … on … equals …
- GroupJoin: join … in … on … equals …?into …?
三、LINQ的特性
1、延遲執(zhí)行查詢
LINQ具有“延遲計(jì)算”的特性。
Linq的執(zhí)行不是在Linq的賦值語句執(zhí)行,而是在通過foreach遍歷訪問結(jié)果時(shí)執(zhí)行。
var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };
var namesWithJ = (from n in names
where n.StartsWith("J")
orderby n
select n);
Console.WriteLine("First iteration");
foreach (string name in namesWithJ)
{
Console.WriteLine(name);
}
Console.WriteLine();
names.Add("John");
names.Add("Jim");
names.Add("Jack");
names.Add("Denny");
Console.WriteLine("Second iteration");
foreach (string name in namesWithJ)
{
Console.WriteLine(name);
}
返回的結(jié)果是:
兩次遍歷的結(jié)果不一樣,說明執(zhí)行并不是在Linq的定義語句執(zhí)行,而是在foreach執(zhí)行。
換成如下,兩次執(zhí)行結(jié)果就一樣了。
var namesWithJ = (from n in names
where n.StartsWith("J")
orderby n
select n
).ToList();
2、運(yùn)算符延遲計(jì)算符號(hào)
按字母順序整理:
1、具有延遲計(jì)算的運(yùn)算符
Cast,Concat,DefaultIfEmpty,Distinct,Except,GroupBy,GroupJoin,Intersect,Join,OfType,OrderBy,OrderByDescending,Repeat,Reverse,Select,SelectMany,Skip,SkipWhile,Take,TakeWhile,ThenBy,ThenByDescending,Union,Where,Zip
2、立即執(zhí)行的運(yùn)算符
對(duì)一系列源元素執(zhí)行聚合函數(shù)的查詢必須首先循環(huán)訪問這些元素。Count、Max、Average?和?First?就屬于此類查詢。
由于查詢本身必須使用?foreach?以便返回結(jié)果,因此這些查詢?cè)趫?zhí)行時(shí)不使用顯式?foreach?語句,直接立即執(zhí)行。
Aggregate,All,Any,Average,Contains,Count,ElementAt,ElementAtOrDefault,Empty,F(xiàn)irst,F(xiàn)irstOrDefault,Last,LastOrDefault,LongCount,Max,Min,Range,SequenceEqual,Single,SingleOrDefault,Sum,ToArray,ToDictionary,ToList,ToLookup
注意:特殊的AsEnumerable運(yùn)算符,用于處理LINQ to Entities操作遠(yuǎn)程數(shù)據(jù)源,將IQueryable遠(yuǎn)程數(shù)據(jù)立即轉(zhuǎn)化為本地的IEnumerable集合。若AsEnumerable接收參數(shù)是IEnumerable內(nèi)存集合則什么都不做。
3、強(qiáng)制立即執(zhí)行
若要強(qiáng)制立即執(zhí)行任意查詢并緩存其結(jié)果,可以調(diào)用?ToList<TSource>?或?ToArray<TSource>?方法。
通過調(diào)用?ToList?或?ToArray,可以將所有數(shù)據(jù)緩存在單個(gè)集合對(duì)象中。
var numQuery2 =
(from num in numbers
where (num % 2) == 0
select num).ToList();
var numQuery3 =
(from num in numbers
where (num % 2) == 0
select num).ToArray();
四、使用 LINQ 進(jìn)行數(shù)據(jù)轉(zhuǎn)換
語言集成查詢 (LINQ) 不僅可用于檢索數(shù)據(jù),而且還是一個(gè)功能強(qiáng)大的數(shù)據(jù)轉(zhuǎn)換工具。
通過使用 LINQ 查詢,您可以將源序列用作輸入,并采用多種方式修改它以創(chuàng)建新的輸出序列。您可以通過排序和分組來修改該序列,而不必修改元素本身。
但是,LINQ 查詢的最強(qiáng)大的功能是能夠創(chuàng)建新類型。這一功能在?select?子句中實(shí)現(xiàn)。
例如,可以執(zhí)行下列任務(wù):
1、將多個(gè)輸入聯(lián)接到一個(gè)輸出序列
class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
public List<int> Scores { get; set; }
}
class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
private static void Main(string[] args)
{
//創(chuàng)建第一個(gè)數(shù)據(jù)源
var students = new List<Student>() {
new Student () {
Age = 23,
City = "廣州",
Name = "小C",
Scores = new List<int> () { 85, 88, 83, 97 }
},
new Student () {
Age = 18,
City = "廣西",
Name = "小明",
Scores = new List<int> () { 86, 78, 85, 90 }
},
new Student () {
Age = 33,
City = "夢(mèng)里",
Name = "小叁",
Scores = new List<int> () { 86, 68, 73, 97 }
}
};
//創(chuàng)建第二個(gè)數(shù)據(jù)源
var teachers = new List<Teacher>() {
new Teacher () {
Age = 35,
City = "夢(mèng)里",
Name = "啵哆"
},
new Teacher () {
Age = 28,
City = "云南",
Name = "小紅"
},
new Teacher () {
Age = 38,
City = "河南",
Name = "麗麗"
}
};
//創(chuàng)建查詢
var peopleInDreams = (from student in students
where student.City == "夢(mèng)里"
select student.Name)
.Concat(from teacher in teachers
where teacher.City == "夢(mèng)里"
select teacher.Name);
//執(zhí)行查詢
foreach (var person in peopleInDreams)
{
Console.WriteLine(person);
}
Console.Read();
}
結(jié)果
小叁?
啵哆
2、選擇各個(gè)源元素的子集
1. 若要只選擇源元素的一個(gè)成員,請(qǐng)使用點(diǎn)運(yùn)算。
var query = from cust in Customers
select cust.City;
2. 若要?jiǎng)?chuàng)建包含源元素的多個(gè)屬性的元素,可以使用具有命名對(duì)象或匿名類型的對(duì)象初始值設(shè)定項(xiàng)。
var query = from cust in Customer
select new {Name = cust.Name, City = cust.City};
3、將內(nèi)存中的對(duì)象轉(zhuǎn)換為 XML
//創(chuàng)建數(shù)據(jù)源
var students = new List<Student>()
{
new Student()
{
Age = 18,
Name = "小A",
Scores = new List<int>() {88,85,74,66 }
},
new Student()
{
Age = 35,
Name = "小B",
Scores = new List<int>() {88,85,74,66 }
},
new Student()
{
Age = 28,
Name = "小啥",
Scores = new List<int>() {88,85,74,66 }
}
};
//創(chuàng)建查詢
var studentsToXml = new XElement("Root",
from student in students
let x = $"{student.Scores[0]},{student.Scores[1]},{student.Scores[2]},{student.Scores[3]}"
select new XElement("student",
new XElement("Name", student.Name),
new XElement("Age", student.Age),
new XElement("Scores", x))
);
//執(zhí)行查詢
Console.WriteLine(studentsToXml);
4、 對(duì)源元素執(zhí)行操作
輸出序列可能不包含源序列的任何元素或元素屬性。
輸出可能是通過將源元素用作輸入?yún)?shù)計(jì)算出的值的序列。
//數(shù)據(jù)源
double[] radii = { 1, 2, 3 };
//創(chuàng)建查詢
var query = from radius in radii
select $"{radius * radius * 3.14}";
//執(zhí)行查詢
foreach (var i in query)
{
Console.WriteLine(i);
}
原文鏈接:https://www.cnblogs.com/springsnow/p/11286711.html
相關(guān)推薦
- 2022-04-25 Pycharm報(bào)錯(cuò):'NoneType'?object?has?no?attribute?'byte
- 2022-07-22 CSS3:盒陰影、邊界圖片、指定每一個(gè)圓角、背景、過度、動(dòng)畫、
- 2022-05-08 python列表的構(gòu)造方法list()_python
- 2022-08-26 一篇文章搞懂Go語言中的Context_Golang
- 2023-04-02 GoLang調(diào)用鏈可視化go-callvis使用介紹_Golang
- 2022-08-21 golang協(xié)程與線程區(qū)別簡(jiǎn)要介紹_Golang
- 2023-02-09 最新解決'nvidia-smi'?不是內(nèi)部或外部命令也不是可運(yùn)行的程序_python
- 2022-11-15 python重用父類功能的兩種方式實(shí)例詳解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支