linq php,C#开始使用 LINQ (上)
LINQ 簡介
語言集成查詢 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的一項創(chuàng)新功能。
傳統(tǒng)上,針對數(shù)據(jù)的查詢都是以簡單的字符串表示,而沒有編譯時類型檢查或 IntelliSense 支持。此外,您還必須針對以下各種數(shù)據(jù)源學(xué)習(xí)一種不同的查詢語言:SQL 數(shù)據(jù)庫、XML 文檔、各種 Web 服務(wù)等等。 通過LINQ, 您可以使用語言關(guān)鍵字和熟悉的運算符針對強類型化對象集合編寫查詢。
在 Visual Studio 中,可以為以下數(shù)據(jù)源編寫 LINQ 查詢:SQL Server 數(shù)據(jù)庫、XML 文檔、ADO.NET 數(shù)據(jù)集,以及支持 IEnumerable 或泛型 IEnumerable 接口的任意對象集合。
使用要求:項目 ≥ .NET Framework 3.5 。
一、介紹 LINQ 查詢
查詢是一種從數(shù)據(jù)源檢索數(shù)據(jù)的表達式。隨著時間的推移,人們已經(jīng)為各種數(shù)據(jù)源開發(fā)了不同的語言;例如,用于關(guān)系數(shù)據(jù)庫的 SQL 和用于 XML 的 XQuery。因此,開發(fā)人員不得不針對他們必須支持的每種數(shù)據(jù)源或數(shù)據(jù)格式而學(xué)習(xí)新的查詢語言。
LINQ 通過提供一種跨數(shù)據(jù)源和數(shù)據(jù)格式使用數(shù)據(jù)的一致模型,簡化了這一情況。在 LINQ 查詢中,始終會用到對象。可以使用相同的編碼模式來查詢和轉(zhuǎn)換 XML 文檔、SQL 數(shù)據(jù)庫、ADO.NET 數(shù)據(jù)集、.NET 集合中的數(shù)據(jù)以及對其有 LINQ 提供程序可用的任何其他格式的數(shù)據(jù)。
1.1 查詢操作的三個部分
操作三部曲:①取數(shù)據(jù)源 ②創(chuàng)建查詢 ③執(zhí)行查詢internal class Program
{
private static void Main(string[] args)
{
//1.獲取數(shù)據(jù)源
var nums = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
//2.創(chuàng)建查詢
var numQuery =
from num in nums
where (num % 2) == 0
select num;
//3.執(zhí)行查詢
foreach (var num in numQuery)
{
Console.WriteLine("{0}", num);
}
}
}
結(jié)果:0
2
4
6
下圖顯示了完整的查詢操作。在 LINQ 中,查詢的執(zhí)行與查詢本身截然不同;換句話說,查詢本身指的是只創(chuàng)建查詢變量,不檢索任何數(shù)據(jù)。
1.2 數(shù)據(jù)源
在上一個示例中,由于數(shù)據(jù)源是數(shù)組,因此它隱式支持泛型 IEnumerable 接口。支持 IEnumerable 或派生接口(如泛型 IQueryable)的類型稱為可查詢類型。
可查詢類型不需要進行修改或特殊處理就可以用作 LINQ 數(shù)據(jù)源。如果源數(shù)據(jù)還沒有作為可查詢類型出現(xiàn)在內(nèi)存中,則 LINQ 提供程序必須以此方式表示源數(shù)據(jù)。例如,LINQ to XML 將 XML 文檔加載到可查詢的 XElement 類型中://從 XML 中創(chuàng)建數(shù)據(jù)源
//using System.Xml.Linq;
var contacts = XElement.Load(@"c:\xxx.xml");
在 LINQ to SQL 中,首先需要創(chuàng)建對象關(guān)系映射。 針對這些對象編寫查詢,然后由 LINQ to SQL 在運行時處理與數(shù)據(jù)庫的通信。var db = new Northwnd(@"c:\northwnd.mdf");
//查詢在倫敦的客戶
var custQuery= from cust in db.Customers
where cust.City == "London"
select cust;
Customers 表示數(shù)據(jù)庫中的特定表
1.3 查詢
查詢指定要從數(shù)據(jù)源中檢索的信息。 查詢還可以指定在返回這些信息之前如何對其進行排序、分組和結(jié)構(gòu)化。 查詢存儲在查詢變量中,并用查詢表達式進行初始化。
之前的示例中的查詢是從整數(shù)數(shù)組中返回所有的偶數(shù)。 該查詢表達式包含三個子句:from、where 和 select。(如果您熟悉 SQL,您會注意到這些子句的順序與 SQL 中的順序相反。)from 子句指定數(shù)據(jù)源,where 子句指定應(yīng)用篩選器,select 子句指定返回的元素的類型。 目前需要注意的是,在 LINQ 中,查詢變量本身不執(zhí)行任何操作并且不返回任何數(shù)據(jù)。 它只是存儲在以后某個時刻執(zhí)行查詢時為生成結(jié)果而必需的信息。
1.4 查詢執(zhí)行
1.延遲執(zhí)行
如前所述,查詢變量本身只是存儲查詢命令。 實際的查詢執(zhí)行會延遲到在 foreach 語句中循環(huán)訪問查詢變量時發(fā)生。 此概念稱為“延遲執(zhí)行”。
2.強制立即執(zhí)行
對一系列源元素執(zhí)行聚合函數(shù)的查詢必須首先循環(huán)訪問這些元素。Count、Max、Average 和 First 就屬于此類查詢。由于查詢本身必須使用 foreach 以便返回結(jié)果,因此這些查詢在執(zhí)行時不使用顯式 foreach 語句。另外還要注意,這些類型的查詢返回單個值,而不是 IEnumerable 集合。var numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
var evenNumQuery =
from num in numbers
where (num % 2) == 0
select num;
var evenNumCount = evenNumQuery.Count();
結(jié)果:4
若要強制立即執(zhí)行任意查詢并緩存其結(jié)果,可以調(diào)用 ToList 或 ToArray 方法。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();
此外,還可以通過在緊跟查詢表達式之后的位置放置一個 foreach 循環(huán)來強制執(zhí)行查詢。但是,通過調(diào)用 ToList 或 ToArray,也可以將所有數(shù)據(jù)緩存在單個集合對象中。
二、基本 LINQ 查詢操作
2.1 獲取數(shù)據(jù)源:from
在 LINQ 查詢中,第一步是指定數(shù)據(jù)源。像在大多數(shù)編程語言中一樣,必須先聲明變量,才能使用它。在 LINQ 查詢中,最先使用 from 子句的目的是引入數(shù)據(jù)源和范圍變量。//queryAllCustomers 是 IEnumerable 類型
//數(shù)據(jù)源 (customers) 和范圍變量 (cust)
var queryAllCustomers = from cust in customers
select cust;
范圍變量類似于 foreach 循環(huán)中的迭代變量,但在查詢表達式中,實際上不發(fā)生迭代。執(zhí)行查詢時,范圍變量將用作對 customers 中的每個后續(xù)元素的引用。因為編譯器可以推斷 cust 的類型,所以您不必顯式指定此類型。
2.2 篩選:where
也許最常用的查詢操作是應(yīng)用布爾表達式形式的篩選器。此篩選器使查詢只返回那些表達式結(jié)果為 true 的元素。使用 where 子句生成結(jié)果。實際上,篩選器指定從源序列中排除哪些元素。var queryLondonCustomers = from cust in customers
where cust.City = "London"
select cust;
您可以使用熟悉的 C# 邏輯 AND(&&)和 OR(||) 運算符來根據(jù)需要在 where 子句中應(yīng)用任意數(shù)量的篩選表達式。where cust.City = "London" && cust.Name = "Devon"
where cust.City = "London" || cust.Name = "Paris"
2.3 排序:orderby
通常可以很方便地將返回的數(shù)據(jù)進行排序。orderby 子句將使返回的序列中的元素按照被排序的類型的默認比較器進行排序。var queryLondonCustomers = from cust in customers
where cust.City = "London"
orderby cust.Name descending
select cust;
因為 Name 是一個字符串,所以默認比較器執(zhí)行從 A 到 Z 的字母排序。若要按相反順序(從 Z 到 A)對結(jié)果進行排序,請使用 orderby…descending 子句。
2.4 分組:group
使用 group 子句,您可以按指定的鍵分組結(jié)果。var queryLondonCustomers = from cust in customers
group cust by cust.City;
foreach (var queryLondonCustomer in queryLondonCustomers)
{
Console.WriteLine(queryLondonCustomer.Key);
foreach (var cust in queryLondonCustomer)
{
Console.WriteLine(cust.Name);
}
}
您可以指定結(jié)果應(yīng)按 City 分組,以便位于倫敦或巴黎的所有客戶位于各自組中。
在本例中,cust.City 是鍵。
在使用 group 子句結(jié)束查詢時,結(jié)果采用列表的列表形式。列表中的每個元素是一個具有 Key 成員及根據(jù)該鍵分組的元素列表的對象。在循環(huán)訪問生成組序列的查詢時,您必須使用嵌套的 foreach 循環(huán)。外部循環(huán)用于循環(huán)訪問每個組,內(nèi)部循環(huán)用于循環(huán)訪問每個組的成員。
如果您必須引用組操作的結(jié)果,可以使用 into 關(guān)鍵字來創(chuàng)建可進一步查詢的標識符。//custQuery 是 IEnumable> 類型
var custQuery = from cust in customers
group cust by cust.City
into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;
這里的查詢只返回那些包含兩個以上的客戶的組。
2.5 聯(lián)接:join
聯(lián)接運算創(chuàng)建數(shù)據(jù)源中沒有顯式建模的序列之間的關(guān)聯(lián)。例如,您可以執(zhí)行聯(lián)接來查找位于同一地點的所有客戶和經(jīng)銷商。在 LINQ 中,join 子句始終針對對象集合而非直接針對數(shù)據(jù)庫表運行。var innerJoinQuery = from cust in customers
join dist in distributors on cust.City equals dist.City
select new {CustomerName = cust.Name, DistributorName = dist.Name};
在 LINQ 中,join 子句始終針對對象集合而非直接針對數(shù)據(jù)庫表運行。
在 LINQ 中,您不必像在 SQL 中那樣頻繁使用 join,因為 LINQ 中的外鍵在對象模型中表示為包含項集合的屬性。
from order in Customer.Orders...
2.6 選擇(投影):select
select 子句生成查詢結(jié)果并指定每個返回的元素的“形狀”或類型。
例如,您可以指定結(jié)果包含的是整個 Customer 對象、僅一個成員、成員的子集,還是某個基于計算或新對象創(chuàng)建的完全不同的結(jié)果類型。當(dāng) select 子句生成除源元素副本以外的內(nèi)容時,該操作稱為“投影”。
三、使用 LINQ 進行數(shù)據(jù)轉(zhuǎn)換
語言集成查詢 (LINQ) 不僅可用于檢索數(shù)據(jù),而且還是一個功能強大的數(shù)據(jù)轉(zhuǎn)換工具。通過使用 LINQ 查詢,您可以將源序列用作輸入,并采用多種方式修改它以創(chuàng)建新的輸出序列。您可以通過排序和分組來修改該序列,而不必修改元素本身。但是,LINQ 查詢的最強大的功能是能夠創(chuàng)建新類型。這一功能在 select 子句中實現(xiàn)。 例如,可以執(zhí)行下列任務(wù):
3.1 將多個輸入聯(lián)接到一個輸出序列class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
public List 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; }
}
學(xué)生和老師兩個類internal class Program
{
private static void Main(string[] args)
{
//創(chuàng)建第一個數(shù)據(jù)源
var students = new List()
{
new Student()
{
Age = 23,
City = "廣州",
Name = "小C",
Scores = new List(){85,88,83,97}
},
new Student()
{
Age = 18,
City = "廣西",
Name = "小明",
Scores = new List(){86,78,85,90}
},
new Student()
{
Age = 33,
City = "夢里",
Name = "小叁",
Scores = new List(){86,68,73,97}
}
};
//創(chuàng)建第二個數(shù)據(jù)源
var teachers = new List()
{
new Teacher()
{
Age = 35,
City = "夢里",
Name = "啵哆"
},
new Teacher()
{
Age = 28,
City = "云南",
Name = "小紅"
},
new Teacher()
{
Age = 38,
City = "河南",
Name = "麗麗"
}
};
//創(chuàng)建查詢
var peopleInDreams = (from student in students
where student.City == "夢里"
select student.Name)
.Concat(from teacher in teachers
where teacher.City == "夢里"
select teacher.Name);
//執(zhí)行查詢
foreach (var person in peopleInDreams)
{
Console.WriteLine(person);
}
Console.Read();
}
}
以上就是C#開始使用 LINQ (上)的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP中文網(wǎng)(www.php.cn)!
本文原創(chuàng)發(fā)布php中文網(wǎng),轉(zhuǎn)載請注明出處,感謝您的尊重!
總結(jié)
以上是生活随笔為你收集整理的linq php,C#开始使用 LINQ (上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lamp不解析php,lamp环境无法解
- 下一篇: c java python html_如