免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Linq 語句學(xué)習(xí)1
LinQ 查詢 1 LINQ查詢概述
LINQ可以對多種數(shù)據(jù)源和對象進(jìn)行查詢,如數(shù)據(jù)庫、數(shù)據(jù)集、XML文檔甚至是數(shù)組,這在傳統(tǒng)的查詢語句中是很難實現(xiàn)的。如果有一個集合類型的值需要進(jìn)行查詢,則必須使用Where等方法進(jìn)行遍歷,而使用LINQ可以仿真SQL語句的形式進(jìn)行查詢,極大的降低了難度。
1 準(zhǔn)備數(shù)據(jù)源
既然LINQ可以查詢多種數(shù)據(jù)源和對象,這些對象可能是數(shù)組,可能是數(shù)據(jù)集,也可能是數(shù)據(jù)庫,那么在使用LINQ進(jìn)行數(shù)據(jù)查詢時首先需要準(zhǔn)備數(shù)據(jù)源。
1.?dāng)?shù)組
數(shù)組中的數(shù)據(jù)可以被LINQ查詢語句查詢,這樣就省去了復(fù)雜的數(shù)組遍歷。數(shù)組數(shù)據(jù)源示例代碼如下所示。
-C#string[] str = { "學(xué)習(xí)", "學(xué)習(xí)LINQ", "好好學(xué)習(xí)", "生活很美好" };
int[] inter = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
數(shù)組可以看成是一個集合,雖然數(shù)組沒有集合的一些特性,但是從另一個角度上來說可以看成是一個集合。在傳統(tǒng)的開發(fā)過程中,如果要篩選其中包含“學(xué)習(xí)”字段的某個字符串,則需要遍歷整個數(shù)組。
2.SQL Server
在數(shù)據(jù)庫操作中,同樣可以使用LINQ進(jìn)行數(shù)據(jù)庫查詢。LINQ以其優(yōu)雅的語法和面向?qū)ο蟮乃枷肽軌蚍奖愕倪M(jìn)行數(shù)據(jù)庫操作,為了使用LINQ進(jìn)行SQL Server數(shù)據(jù)庫查詢,可以創(chuàng)建兩個表,這兩個表的結(jié)構(gòu)如下所示。Student(學(xué)生表):
1)S_ID:學(xué)生ID。
2)S_NAME:學(xué)生姓名。
3)S_CLASS:學(xué)生班級。
4)C_ID:所在班級的ID。
上述結(jié)構(gòu)描述了一個學(xué)生表,可以使用SQL語句創(chuàng)建學(xué)生表,示例代碼如下所示。
-SQL   USE [student]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Student](
[S_ID] [int] IDENTITY(1,1) NOT NULL,
[S_NAME] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[S_CLASS] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[C_ID] [int] NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[S_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
為了更加詳細(xì)的描述一個學(xué)生所有的基本信息,就需要創(chuàng)建另一個表對該學(xué)生所在的班級進(jìn)行描述,班級表結(jié)構(gòu)如下所示。Class(班級表):
1)C_ID:班級ID。
2)C_GREAD:班級所在的年級。
3)C_INFOR:班級專業(yè)。
上述代碼描述了一個班級的基本信息,同樣可以使用SQL語句創(chuàng)建班級表,示例代碼如下所示。
-SQL    USE [student]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Class](
[C_ID] [int] IDENTITY(1,1) NOT NULL,
[C_GREAD] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[C_INFOR] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED
(
[C_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
上述代碼在Student數(shù)據(jù)庫中創(chuàng)建了一個班級表,開發(fā)人員能夠向數(shù)據(jù)庫中添加相應(yīng)的信息以準(zhǔn)備數(shù)據(jù)源。
3.?dāng)?shù)據(jù)集
LINQ能夠通過查詢數(shù)據(jù)集進(jìn)行數(shù)據(jù)的訪問和整合;通過訪問數(shù)據(jù)集,LINQ能夠返回一個集合變量;通過遍歷集合變量可以進(jìn)行其中數(shù)據(jù)的訪問和篩選。在第9章中講到了數(shù)據(jù)集的概念,開發(fā)人員能夠?qū)?shù)據(jù)庫中的內(nèi)容填充到數(shù)據(jù)集中,也可以自行創(chuàng)建數(shù)據(jù)集。
數(shù)據(jù)集是一個存在于內(nèi)存的對象,該對象能夠模擬數(shù)據(jù)庫的一些基本功能,可以模擬小型的數(shù)據(jù)庫系統(tǒng),開發(fā)人員能夠使用數(shù)據(jù)集對象在內(nèi)存中創(chuàng)建表,以及模擬表與表之間的關(guān)系。在數(shù)據(jù)集的數(shù)據(jù)檢索過程中,往往需要大量的if、else等判斷才能檢索相應(yīng)的數(shù)據(jù)。
使用LINQ進(jìn)行數(shù)據(jù)集中數(shù)據(jù)的整理和檢索可以減少代碼量并優(yōu)化檢索操作。數(shù)據(jù)集可以是開發(fā)人員自己創(chuàng)建的數(shù)據(jù)集也可以是現(xiàn)有數(shù)據(jù)庫填充的數(shù)據(jù)集,這里使用上述SQL Server創(chuàng)建的數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行數(shù)據(jù)集的填充。
2 使用LINQ
在傳統(tǒng)對象查詢中,往往需要很多的if、else語句進(jìn)行數(shù)組或?qū)ο蟮谋闅v,例如在數(shù)組中尋找相應(yīng)的字段,實現(xiàn)起來往往比較復(fù)雜,而使用LINQ就簡化了對象的查詢。由于前面已經(jīng)準(zhǔn)備好了數(shù)據(jù)源,那么就能夠分別使用LINQ語句進(jìn)行數(shù)據(jù)源查詢。
1.?dāng)?shù)組
在前面的章節(jié)中,已經(jīng)創(chuàng)建了一個數(shù)組作為數(shù)據(jù)源,數(shù)組示例代碼如下所示。
-C#int[] inter = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
上述代碼是一個數(shù)組數(shù)據(jù)源,如果開發(fā)人員需要從其中的元素中搜索大于5的數(shù)字,傳統(tǒng)的方法應(yīng)該遍歷整個數(shù)組并判斷該數(shù)字是否大于5,如果大于5則輸出,否則不輸出,示例代碼如下所示。
-C#using System;
using System.Collections.Generic;
using System.Linq;//使用必要的命名空間
using System.Text;
namespace _21_1
{
class Program
{
static void Main(string[] args)
{
string[] str = { "學(xué)習(xí)", "學(xué)習(xí)LINQ", "好好學(xué)習(xí)", "生活很美好" };//定義數(shù)組
int[] inter = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i = 0; i < inter.Length; i++)//遍歷數(shù)組
{
if (inter[i] > 5)//判斷數(shù)組元素的值是否大于5
{
Console.WriteLine(inter[i].ToString());//輸出對象
}
}
Console.ReadKey();
}
}
}
上述代碼非常簡單,將數(shù)組從頭開始遍歷,遍歷中將數(shù)組中的的值與5相比較,如果大于5就會輸出該值,如果小于5就不會輸出該值。雖然上述代碼實現(xiàn)了功能的要求,但是這樣編寫的代碼繁冗復(fù)雜,也不具有擴展性。如果使用LINQ查詢語句進(jìn)行查詢就非常簡單,示例代碼如下所示。
-C#    class Program
{
static void Main(string[] args)
{
string[] str = { "學(xué)習(xí)", "學(xué)習(xí)LINQ", "好好學(xué)習(xí)", "生活很美好" };//定義數(shù)組
int[] inter = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //定義數(shù)組
var st = from s in inter where s > 5  select s;//執(zhí)行LINQ查詢語句
foreach (var t in st) //遍歷集合元素
{
Console.WriteLine(t.ToString());//輸出數(shù)組
}
Console.ReadKey();
}
}
使用LINQ進(jìn)行查詢之后會返回一個IEnumerable的集合。在上一章講過,IEnumerable是.NET框架中最基本的集合訪問器,可以使用foreach語句遍歷集合元素。使用LINQ查詢數(shù)組更加容易被閱讀,LINQ查詢語句的結(jié)構(gòu)和SQL語法十分類似,LINQ不僅能夠查詢數(shù)組,還可以通過.NET提供的編程語言進(jìn)行篩選。例如str數(shù)組變量,如果要查詢其中包含“學(xué)習(xí)”的字符串,對于傳統(tǒng)的編程方法是非常冗余和繁瑣的。由于LINQ是.NET編程語言中的一部分,開發(fā)人員就能通過編程語言進(jìn)行篩選,LINQ查詢語句示例代碼如下所示。
-C#var st = from s in str where s.Contains("學(xué)習(xí)")  select s;
2.使用SQL Server
在傳統(tǒng)的數(shù)據(jù)庫開發(fā)中,如果需要篩選某個數(shù)據(jù)庫中的數(shù)據(jù),可以通過SQL語句進(jìn)行篩選。在ADO.NET中,首先需要從數(shù)據(jù)庫中查詢數(shù)據(jù),查詢后就必須將數(shù)據(jù)填充到數(shù)據(jù)集中,然后在數(shù)據(jù)集中進(jìn)行數(shù)據(jù)遍歷,示例代碼如下所示。
-C#            try
{
SqlConnection
con = new SqlConnection("server='(local)';database='student';uid='sa';pwd='sa'");//創(chuàng)建連接
con.Open();//打開連接
string strsql = "select * from student,class where student.c_id=class.c_id";//SQL語句
SqlDataAdapter da = new SqlDataAdapter(strsql, con);//創(chuàng)建適配器
DataSet ds = new DataSet();//創(chuàng)建數(shù)據(jù)集
int j = da.Fill(ds, "mytable");//填充數(shù)據(jù)集
for (int i = 0; i < j; i++)//遍歷集合
{
Console.WriteLine(ds.Tables["mytable"].Rows[i]["S_NAME"].ToString());//輸出對象
}
}
catch
{
Console.WriteLine("數(shù)據(jù)庫連接錯誤");//拋出異常
}
上述代碼進(jìn)行數(shù)據(jù)庫的訪問和查詢。在上述代碼中,首先需要創(chuàng)建一個連接對象進(jìn)行數(shù)據(jù)庫連接,然后再打開連接,打開連接之后就要編寫SELECT語句進(jìn)行數(shù)據(jù)庫查詢并填充到DataSet數(shù)據(jù)集中,并在DataSet數(shù)據(jù)集中遍歷相應(yīng)的表和列進(jìn)行數(shù)據(jù)篩選。如果要查詢C_ID為1的學(xué)生的所有姓名,有三個辦法,這三個辦法分別是:
1)修改SQL語句。
2)在循環(huán)內(nèi)進(jìn)行判斷。
3)使用LINQ進(jìn)行查詢。
修改SQL語句是最方便的方法,直接在SELECT語句中添加查詢條件WHERE C-ID=1就能夠?qū)崿F(xiàn),但是這個方法擴展性非常的低,如果有其他需求則就需要修改SQL語句,也有可能造成其余代碼填充數(shù)據(jù)集后數(shù)據(jù)集內(nèi)容不同步。
在循環(huán)內(nèi)進(jìn)行判斷也是一種方法,但是這個方法當(dāng)循環(huán)增加時會造成額外的性能消耗,并且當(dāng)需要擴展時,還需要修改循環(huán)代碼。最方便的就是使用LINQ進(jìn)行查詢,在Visual Studio 2008中提供了LINQ to SQL類文件用于將現(xiàn)有的數(shù)據(jù)抽象成對象,這樣就符合了面向?qū)ο蟮脑瓌t,同時也能夠減少代碼,提升擴展性。創(chuàng)建一個LINQ to SQL類文件,直接將服務(wù)資源管理器中的相應(yīng)表拖放到LINQ to SQL類文件可視化窗口中即可,如圖21-1所示。
圖1 創(chuàng)建LINQ to SQL文件
創(chuàng)建了LINQ to SQL類文件后,就可以直接使用LINQ to SQL類文件提供的類進(jìn)行查詢,示例代碼如下所示。
-C#            linqtosqlDataContext lq = new linqtosqlDataContext();
var mylq = from l in lq.Student from cl in lq.Class where l.C_ID==cl.C_ID select l;//執(zhí)行查詢
foreach (var result in mylq) //遍歷集合
{
Console.WriteLine(result.S_NAME.ToString());//輸出對象
}
上述代碼只用了很短的代碼就能夠?qū)崿F(xiàn)數(shù)據(jù)庫中數(shù)據(jù)的查詢和遍歷,并且從可讀性上來說也很容易理解,因為LINQ查詢語句的語法基本與SQL語法相同,只要有一定的SQL語句基礎(chǔ)就能夠非常容易的編寫LINQ查詢語句。
3.?dāng)?shù)據(jù)集
LINQ同樣對數(shù)據(jù)集支持查詢和篩選操作。其實數(shù)據(jù)集也是集合的表現(xiàn)形式,數(shù)據(jù)集除了能夠填充數(shù)據(jù)庫中的內(nèi)容以外,開發(fā)人員還能夠通過對數(shù)據(jù)集的操作向數(shù)據(jù)集中添加數(shù)據(jù)和修改數(shù)據(jù)。前面的章節(jié)中已經(jīng)講到,數(shù)據(jù)集可以看作是內(nèi)存中的數(shù)據(jù)庫。數(shù)據(jù)集能夠模擬基本的數(shù)據(jù)庫,包括表、關(guān)系等。這里就將SQL Server中的數(shù)據(jù)填充到數(shù)據(jù)集即可,示例代碼如下所示。
-C#            try
{
SqlConnection
con = new SqlConnection("server='(local)';database='student';uid='sa';pwd='sa'");//創(chuàng)建連接
con.Open();//打開連接
string strsql = "select * from student,class where student.c_id=class.c_id";//執(zhí)行SQL
SqlDataAdapter da = new SqlDataAdapter(strsql, con);//創(chuàng)建適配器
DataSet ds = new DataSet();//創(chuàng)建數(shù)據(jù)集
da.Fill(ds, "mytable");//填充數(shù)據(jù)集
DataTable tables = ds.Tables["mytable"];//創(chuàng)建表
var dslq = from d in tables.AsEnumerable() select d;//執(zhí)行LINQ語句
foreach (var res in dslq)
{
Console.WriteLine(res.Field<string>("S_NAME").ToString());//輸出對象
}
}
catch
{
Console.WriteLine("數(shù)據(jù)庫連接錯誤");
}
上述代碼使用LINQ針對數(shù)據(jù)集中的數(shù)據(jù)進(jìn)行篩選和整理,同樣能夠以一種面向?qū)ο蟮乃枷脒M(jìn)行數(shù)據(jù)集中數(shù)據(jù)的篩選。在使用LINQ進(jìn)行數(shù)據(jù)集操作時,LINQ不能直接從數(shù)據(jù)集對象中查詢,因為數(shù)據(jù)集對象不支持LINQ查詢,所以需要使用AsEnumerable方法返回一個泛型的對象以支持LINQ的查詢操作,示例代碼如下所示。
-C#var dslq = from d in tables.AsEnumerable() select d;//使用AsEnumerable
上述代碼使用AsEnumerable方法就可以讓數(shù)據(jù)集中的表對象能夠支持LINQ查詢。
3 執(zhí)行LINQ查詢
從上一節(jié)可以看出LINQ在編程過程中極大的方便了開發(fā)人員對于業(yè)務(wù)邏輯的處理代碼的編寫,在傳統(tǒng)的編程方法中復(fù)雜、冗余、難以實現(xiàn)的方法在LINQ中都能很好的解決。LINQ不僅能夠像SQL語句一樣編寫查詢表達(dá)式,LINQ最大的優(yōu)點也包括LINQ作為編程語言的一部分,可以使用編程語言提供的特性進(jìn)行LINQ條件語句的編寫,這就彌補了SQL語句中的一些不足。在前面的章節(jié)中將一些復(fù)雜的查詢和判斷的代碼簡化成LINQ應(yīng)用后,就能夠執(zhí)行應(yīng)用程序判斷LINQ是否查詢和篩選出了所需要的值。
1.?dāng)?shù)組
在數(shù)組數(shù)據(jù)源中,開發(fā)人員希望能夠篩選出大于5的元素。開發(fā)人員將傳統(tǒng)的代碼修改成LINQ代碼并通過LINQ查詢語句進(jìn)行篩選,示例代碼如下所示。
+展開 -C#var st = from s in inter where s > 5  select s;//執(zhí)行LINQ查詢
上述代碼將查詢在inter數(shù)組中的所有元素并返回其中元素的值大于5的元素的集合,運行后如圖21-2所示。
圖2 遍歷數(shù)組
LINQ執(zhí)行了條件語句并返回了元素的值大于5的元素。LINQ語句能夠方便的擴展,當(dāng)有不同的需求時,可以修改條件語句進(jìn)行邏輯判斷,例如可以篩選一個平方數(shù)為偶數(shù)的數(shù)組元素,直接修改條件即可,LINQ查詢語句如下所示。
-C#var st = from s in inter where (s*s)%2==0  select s;//執(zhí)行LINQ查詢
上述代碼通過條件(s*s)%2==0將數(shù)組元素進(jìn)行篩選,選擇平方數(shù)為偶數(shù)的數(shù)組元素的集合,運行后如圖21-3所示。
圖3 更改篩選條件
2.使用SQL Server
在LINQ to SQL類文件中,LINQ to SQL類文件已經(jīng)將數(shù)據(jù)庫的模型封裝成一個對象,開發(fā)人員能夠通過面向?qū)ο蟮乃枷朐L問和整合數(shù)據(jù)庫。LINQ to SQL也對SQL做了補充,使用LINQ to SQL類文件能夠執(zhí)行更強大的篩選,LINQ查詢語句代碼如下所示。
-C#var mylq = from l in lq.Student from cl in lq.Class where l.C_ID==cl.C_ID select l;//執(zhí)行LINQ查詢
上述代碼從Student表和Class表中篩選了C_ID相等的學(xué)生信息,這很容易在SQL語句中實現(xiàn)。LINQ作為編程語言的一部分,可以使用更多的編程方法實現(xiàn)不同的篩選需求,例如篩選名稱中包含“郭”字的學(xué)生的名稱在傳統(tǒng)的SQL語句中就很難通過一條語句實現(xiàn),而在LINQ中就能夠?qū)崿F(xiàn),示例代碼如下所示。
+展開 -C#var mylq = from l in lq.Student from cl in lq.Class where l.C_ID==cl.C_ID where
l.S_NAME.Contains("郭") select l;//執(zhí)行LINQ條件查詢
上述代碼使用了Contains方法判斷一個字符串中是否包含某個字符或字符串,這樣不僅方便閱讀,也簡化了查詢操作,運行后如圖21-4和圖21-5所示。
圖4 簡單查詢
圖5 條件查詢
LINQ返回了符合條件的元素的集合,并實現(xiàn)了篩選操作。LINQ不僅作為編程語言的一部分,簡化了開發(fā)人員的開發(fā)操作,從另一方面講,LINQ也補充了在SQL中難以通過幾條語句實現(xiàn)的功能的實現(xiàn)。從上面的LINQ查詢代碼可以看出,就算是不同的對象、不同的數(shù)據(jù)源,其LINQ基本的查詢語法都非常相似,并且LINQ還能夠支持編程語言具有的特性從而彌補SQL語句的不足。在數(shù)據(jù)集的查詢中,其查詢語句也可以直接使用而無需大面積修改代碼,這樣代碼就具有了更高的維護性和可讀性。
linq 查詢 2 查詢語法
從上面的章節(jié)中可以看出,LINQ查詢語句能夠?qū)?fù)雜的查詢應(yīng)用簡化成一個簡單的查詢語句,不僅如此,LINQ還支持編程語言本有的特性進(jìn)行高效的數(shù)據(jù)訪問和篩選。雖然LINQ在寫法上和SQL語句十分相似,但是LINQ語句在其查詢語法上和SQL語句還是有出入的,SQL查詢語句如下所示。
-C#select * from student,class where student.c_id=class.c_id//SQL查詢語句
上述代碼是SQL查詢語句,對于LINQ而言,其查詢語句格式如下所示。
-C#var mylq = from l in lq.Student from cl in lq.Class where l.C_ID==cl.C_ID select l;//LINQ查詢語句
上述代碼作為LINQ查詢語句實現(xiàn)了同SQL查詢語句一樣的效果,但是LINQ查詢語句在格式上與SQL語句不同,LINQ的基本格式如下所示。
-C#var <變量> = from <項目> in <數(shù)據(jù)源> where <表達(dá)式> orderby <表達(dá)式>
LINQ語句不僅能夠支持對數(shù)據(jù)源的查詢和篩選,同SQL語句一樣,還支持ORDER BY等排序,以及投影等操作,示例查詢語句如下所示。
-C#var st = from s in inter where s==3 select s;//LINQ查詢
var st = from s in inter where (s * s) % 2 == 0 orderby s descending select s;//LINQ條件查詢
從結(jié)構(gòu)上來看,LINQ查詢語句同SQL查詢語句中比較大的區(qū)別就在于SQL查詢語句中的SELECT關(guān)鍵字在語句的前面,而在LINQ查詢語句中SELECT關(guān)鍵字在語句的后面,在其他地方?jīng)]有太大的區(qū)別,對于熟悉SQL查詢語句的人來說非常容易上手。
既然LINQ查詢語句同SQL查詢語句一樣,能夠執(zhí)行條件、排序等操作,這些操作就需要使用WHERE、ORDERBY等關(guān)鍵字,這些關(guān)鍵字在LINQ中是基本子句。同SQL查詢語句中的WHERE、ORDER BY操作一樣,都為元素進(jìn)行整合和篩選。
21.3.1 from查詢子句
from子句是LINQ查詢語句中最基本也是最關(guān)鍵的子句關(guān)鍵字,與SQL查詢語句不同的是,from關(guān)鍵字必須在LINQ查詢語句的開始。
1.from查詢子句基礎(chǔ)
后面跟隨著項目名稱和數(shù)據(jù)源,示例代碼如下所示。
var linqstr = from lq in str select lq;//form子句
from語句指定項目名稱和數(shù)據(jù)源,并且指定需要查詢的內(nèi)容,其中項目名稱作為數(shù)據(jù)源的一部分而存在,用于表示和描述數(shù)據(jù)源中的每個元素,而數(shù)據(jù)源可以是數(shù)組、集合、數(shù)據(jù)庫甚至是XML。值得一提的是,from子句的數(shù)據(jù)源的類型必須為IEnumerable、IEnumerable<T>類型或者是IEnumerable、IEnumerable<T>的派生類,否則from不能夠支持LINQ查詢語句。
在.NET Framework中泛型編程中,List(可通過索引的強類型列表)也能夠支持LINQ查詢語句的from關(guān)鍵字,因為List實現(xiàn)了IEnumerable、IEnumerable<T>類型,在LINQ中可以對List類進(jìn)行查詢,示例代碼如下所示。
static void Main(string[] args)
{
List<string> MyList = new List<string>();//創(chuàng)建一個列表項
MyList.Add("guojing");//添加一項
MyList.Add("wujunmin");//添加一項
MyList.Add("muqing"); //添加一項
var linqstr = from l in MyList select l;//LINQ查詢
foreach (var element in linqstr)//遍歷集合
{
Console.WriteLine(element.ToString());//輸出對象
}
Console.ReadKey();
}
上述代碼創(chuàng)建了一個列表項并向列表中添加若干項進(jìn)行LINQ查詢。由于List<T>實現(xiàn)了IEnumerable、IEnumerable<T>,所以List<T>列表項可以支持LINQ查詢語句的from關(guān)鍵字,如圖 6所示。
圖 6 from子句
顧名思義,from語句可以被理解為“來自”,而in可以被理解為“在哪個數(shù)據(jù)源中”,這樣from語句就很好理解了,如from l in MyList select l語句可以翻譯成“找到來自MyList數(shù)據(jù)源中的集合l”,這樣就能夠更加方便的理解from語句。
2.from查詢子句嵌套查詢
在SQL語句中,為了實現(xiàn)某一功能,往往需要包含多個條件,以及包含多個SQL子句嵌套。在LINQ查詢語句中,并沒有and關(guān)鍵字為復(fù)合查詢提供功能。如果需要進(jìn)行復(fù)雜的復(fù)合查詢,可以在from子句中嵌套另一個from子句即可,示例代碼如下所示。
var linqstr = from lq in str from m in str2 select lq;//使用嵌套查詢  上述代碼就使用了一個嵌套查詢進(jìn)行LINQ查詢。在有多個數(shù)據(jù)源或者包括多個表的數(shù)據(jù)需要查詢時,可以使用LINQfrom子句嵌套查詢,數(shù)據(jù)源示例代碼如下所示。            List<string> MyList = new List<string>();//創(chuàng)建一個數(shù)據(jù)源
MyList.Add("guojing");//添加一項
MyList.Add("wujunmin");//添加一項
MyList.Add("muqing"); //添加一項
MyList.Add("yuwen");//添加一項
List<string> MyList2 = new List<string>();//創(chuàng)建另一個數(shù)據(jù)源
MyList2.Add("guojing's phone");//添加一項
MyList2.Add("wujunmin's phone ");//添加一項
MyList2.Add("muqing's phone ");//添加一項
MyList2.Add("lupan's phone ");//添加一項
上述代碼創(chuàng)建了兩個數(shù)據(jù)源,其中一個數(shù)據(jù)源存放了聯(lián)系人的姓名的拼音名稱,另一個則存放了聯(lián)系人的電話信息。為了方便的查詢在數(shù)據(jù)源中“聯(lián)系人”和“聯(lián)系人電話”都存在并且匹配的數(shù)據(jù),就需要使用from子句嵌套查詢,示例代碼如下所示。            var linqstr = from l in MyList from m in MyList2 where m.Contains(l) select l;//from子句嵌套查詢
foreach (var element in linqstr)//遍歷集合元素
{
Console.WriteLine(element.ToString());//輸出對象
}
Console.ReadKey();  上述代碼使用了LINQ語句進(jìn)行嵌套查詢,嵌套查詢在LINQ中會被經(jīng)常使用到,因為開發(fā)人員常常遇到需要面對多個表多個條件,以及不同數(shù)據(jù)源或數(shù)據(jù)源對象的情況,使用LINQ查詢語句的嵌套查詢可以方便的在不同的表和數(shù)據(jù)源對象之間建立關(guān)系。 2 where條件子句
在SQL查詢語句中可以使用where子句進(jìn)行數(shù)據(jù)的篩選,在LINQ中同樣包括where子句進(jìn)行數(shù)據(jù)源中數(shù)據(jù)的篩選。where子句指定了篩選的條件,這也就是說在where子句中的代碼段必須返回布爾值才能夠進(jìn)行數(shù)據(jù)源的篩選,示例代碼如下所示-var linqstr = from l in MyList where l.Length > 5 select l;//編寫where子句  LINQ查詢語句可以包含一個或多個where子句,而where子句可以包含一個或多個布爾值變量,為了查詢數(shù)據(jù)源中姓名的長度在6之上的姓名,可以使用where子句進(jìn)行查詢,示例代碼如下所示。        static void Main(string[] args)
{
List<string> MyList = new List<string>();//創(chuàng)建List對象
MyList.Add("guojing");//添加一項
MyList.Add("wujunmin");//添加一項
MyList.Add("muqing"); //添加一項
MyList.Add("yuwen"); //添加一項
var linqstr = from l in MyList where l.Length > 6 select l;//執(zhí)行where查詢
foreach (var element in linqstr)//遍歷集合
{
Console.WriteLine(element.ToString());//輸出對象
}
Console.ReadKey();
}  上述代碼添加了數(shù)據(jù)源之后,通過where子句在數(shù)據(jù)源中進(jìn)行條件查詢,LINQ查詢語句會遍歷數(shù)據(jù)源中的數(shù)據(jù)并進(jìn)行判斷,如果返回值為true,則會在linqstr集合中添加該元素,運行后如圖 7所示。
圖 7 where子句查詢
當(dāng)需要多個where子句進(jìn)行復(fù)合條件查詢時,可以使用“&&”進(jìn)行where子句的整合,示例代碼如下所示。
static void Main(string[] args)
{
List<string> MyList = new List<string>();//創(chuàng)建List對象
MyList.Add("guojing");//添加一項
MyList.Add("wujunmin");//添加一項
MyList.Add("muqing"); //添加一項
MyList.Add("guomoruo");//添加一項
MyList.Add("lupan");//添加一項
MyList.Add("guof");//添加一項
var linqstr = from l in MyList where (l.Length > 6 && l.Contains("guo"))||l=="lupan" select l;//復(fù)合查詢
foreach (var element in linqstr)//遍歷集合
{
Console.WriteLine(element.ToString());//輸出對象
}
Console.ReadKey();
}   上述代碼進(jìn)行了多條件的復(fù)合查詢,查詢姓名長度大于6并且姓名中包含guo的姓或者姓名是“l(fā)upan”的人,運行后如圖 8所示。
圖 8 復(fù)合where子句查詢
復(fù)合where子句查詢通常用于同一個數(shù)據(jù)源中的數(shù)據(jù)查詢,當(dāng)需要在同一個數(shù)據(jù)源中進(jìn)行篩選查詢時,可以使用where子句進(jìn)行單個或多個where子句條件查詢,where子句能夠?qū)?shù)據(jù)源中的數(shù)據(jù)進(jìn)行篩選并將復(fù)合條件的元素返回到集合中。
3 select選擇子句
select子句同from子句一樣,是LINQ查詢語句中必不可少的關(guān)鍵字,select子句在LINQ查詢語句中是必須的,示例代碼如下所示。var linqstr = from lq in str select lq; //編寫選擇子句
上述代碼中包括三個變量,這三個變量分別為linqstr、lq、str。其中str是數(shù)據(jù)源,linqstr是數(shù)據(jù)源中滿足查詢條件的集合,而lq也是一個集合,這個集合來自數(shù)據(jù)源。在LINQ查詢語句中必須包含select子句,若不包含select子句則系統(tǒng)會拋出異常(除特殊情況外)。select語句指定了返回到集合變量中的元素是來自哪個數(shù)據(jù)源的,示例代碼如下所示。        static void Main(string[] args)
{
List<string> MyList = new List<string>();//創(chuàng)建List
MyList.Add("guojing");//添加一項
MyList.Add("wujunmin");//添加一項
MyList.Add("guomoruo");//添加一項
List<string> MyList2 = new List<string>();//創(chuàng)建List
MyList2.Add("guojing's phone");//添加一項
MyList2.Add("wujunmin's phone ");//添加一項
MyList2.Add("lupan's phone ");//添加一項
var linqstr = from l in MyList from m in MyList2 where m.Contains(l) select l;//select l變量
foreach (var element in linqstr)//遍歷集合
{
Console.WriteLine(element.ToString());//輸出集合內(nèi)容
}
Console.ReadKey();//等待用戶按鍵
}  上述代碼從兩個數(shù)據(jù)源中篩選數(shù)據(jù),并通過select返回集合元素,運行后所示。
select子句
如果將select子句后面的項目名稱更改,則結(jié)果可能不同,更改LINQ查詢子句代碼如下所示。var linqstr = from l in MyList from m in MyList2 where m.Contains(l) select m;//使用select
上述LINQ查詢子句并沒有select l變量中的集合元素,而是選擇了m集合元素,則返回的應(yīng)該是MyList2數(shù)據(jù)源中的集合元素。
select子句
對于不同的select對象返回的結(jié)果也不盡相同,當(dāng)開發(fā)人員需要進(jìn)行復(fù)合查詢時,可以通過select語句返回不同的復(fù)合查詢對象,這在多數(shù)據(jù)源和多數(shù)據(jù)對象查詢中是非常有幫助的。
4 group分組子句
在LINQ查詢語句中,group子句對from語句執(zhí)行查詢的結(jié)果進(jìn)行分組,并返回元素類型為IGrouping<TKey,TElement>的對象序列。group子句支持將數(shù)據(jù)源中的數(shù)據(jù)進(jìn)行分組。但進(jìn)行分組前,數(shù)據(jù)源必須支持分組操作才可使用group語句進(jìn)行分組處理,示例代碼如下所示。 -C#    public class Person
{
public int age; //分組條件
public string name;//創(chuàng)建姓名字段
public Person(int age,string name)//構(gòu)造函數(shù)
{
this.age = age;//構(gòu)造屬性值age
this.name = name;//構(gòu)造屬性值name
}
}
上述代碼設(shè)計了一個類用于描述聯(lián)系人的姓名和年級,并且按照年級進(jìn)行分組,這樣數(shù)據(jù)源就能夠支持分組操作。
注意:雖然數(shù)組也可以進(jìn)行分組操作,因為其絕大部分?jǐn)?shù)據(jù)源都能夠支持分組操作,但是數(shù)組等數(shù)據(jù)源進(jìn)行分組操作可能是沒有意義的。
這里同樣可以通過List列表以支持LINQ查詢,示例代碼如下所示。         static void Main(string[] args)
{
List<Person> PersonList = new List<Person>();
PersonList.Add(new Person(21,"limusha"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(21, "guojing"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(22, "wujunmin"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(22, "lupan"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(23, "yuwen"));//通過構(gòu)造函數(shù)構(gòu)造新對象
var gl = from p in PersonList group p by p.age;//使用group子句進(jìn)行分組
foreach (var element in gl)//遍歷集合
{
foreach (Person p in element)//遍歷集合
{
Console.WriteLine(p.name.ToString());//輸出對象
}
}
Console.ReadKey();
}  上述代碼使用了group子句進(jìn)行數(shù)據(jù)分組,實現(xiàn)了分組的功能,運行后如圖 11所示。
圖 11 group子句
正如圖21-11所示,group子句將數(shù)據(jù)源中的數(shù)據(jù)進(jìn)行分組,在遍歷數(shù)據(jù)元素時,并不像前面的章節(jié)那樣直接對元素進(jìn)行遍歷,因為group子句返回的是元素類型為IGrouping<TKey,TElement>的對象序列,必須在循環(huán)中嵌套一個對象的循環(huán)才能夠查詢相應(yīng)的數(shù)據(jù)元素。
在使用group子句時,LINQ查詢子句的末尾并沒有select子句,因為group子句會返回一個對象序列,通過循環(huán)遍歷才能夠在對象序列中尋找到相應(yīng)的對象的元素,如果使用group子句進(jìn)行分組操作,可以不使用select子句。
5 orderby排序子句
在SQL查詢語句中,常常需要對現(xiàn)有的數(shù)據(jù)元素進(jìn)行排序,例如注冊用戶的時間,以及新聞列表的排序,這樣能夠方便用戶在應(yīng)用程序使用過程中快速獲取需要的信息。在LINQ查詢語句中同樣支持排序操作以提取用戶需要的信息。在LINQ語句中,orderby是一個詞組而不是分開的,orderby能夠支持對象的排序,例如按照用戶的年齡進(jìn)行排序時就可以使用orderby關(guān)鍵字,示例代碼如下所示。
public class Person //創(chuàng)建對象
{
public int age; //創(chuàng)建字段
public string name;//創(chuàng)建字段
public Person(int age,string name)//構(gòu)造函數(shù)
{
this.age = age;//賦值字段
this.name = name;
}
}  上述代碼同樣設(shè)計了一個Person類,并通過age、name字段描述類對象。使用LINQ,同樣要使用List類作為對象的容器并進(jìn)行其中元素的查詢,示例代碼如下所示。    class Program
{
static void Main(string[] args)
{
List<Person> PersonList = new List<Person>();//創(chuàng)建對象列表
PersonList.Add(new Person(21,"limusha"));//年齡為21
PersonList.Add(new Person(23, "guojing"));//年齡為23
PersonList.Add(new Person(22, "wujunmin")); //年齡為22
PersonList.Add(new Person(25, "lupan"));//年齡為25
PersonList.Add(new Person(24, "yuwen"));//年齡為24
var gl = from p in PersonList orderby p.age select p;//執(zhí)行排序操作
foreach (var element in gl)//遍歷集合
{
Console.WriteLine(element.name.ToString());//輸出對象
}
Console.ReadKey();
}
}  上述代碼并沒有按照順序?qū)ist容器添加對象,其中數(shù)據(jù)的顯示并不是按照順序來顯示的。使用orderby關(guān)鍵字能夠指定集合中的元素的排序規(guī)則,上述代碼按照年齡的大小進(jìn)行排序,運行后如圖 12所示。
圖 12 orderby子句
orderby子句同樣能夠?qū)崿F(xiàn)倒序排列,倒序排列在應(yīng)用程序開發(fā)過程中應(yīng)用的非常廣泛,例如新聞等。用戶關(guān)心的都是當(dāng)天的新聞而不是很久以前發(fā)布的某個新聞,如果管理員發(fā)布了一個新的新聞,顯示在最上方的應(yīng)該是最新的新聞。在orderby子句中可以使用descending關(guān)鍵字進(jìn)行倒序排列,示例代碼如下所示。var gl = from p in PersonList orderby p.age descending select p;//orderby語句  上述代碼將用戶的信息按照其年齡的大小倒序排列,運行如圖 13所示。
圖 13 orderby子句倒序
orderby子句同樣能夠進(jìn)行多個條件排序,如果需要使用orderby子句進(jìn)行多個條件排序,只需要將這些條件用“,”號分割即可,示例代碼如下所示var gl = from p in PersonList orderby p.age descending,p.name select p;//orderby語句
6 into連接子句
into子句通常和group子句一起使用,通常情況下,LINQ查詢語句中無需into子句,但是如果需要對分組中的元素進(jìn)行操作,則需要使用into子句。into語句能夠創(chuàng)建臨時標(biāo)識符用于保存查詢的集合,示例代碼如下所示。
static void Main(string[] args)
{
List<Person> PersonList = new List<Person>();//創(chuàng)建對象列表
PersonList.Add(new Person(21, "limusha"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(21, "guojing"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(22, "wujunmin"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(22, "lupan"));//通過構(gòu)造函數(shù)構(gòu)造新對象
PersonList.Add(new Person(23, "yuwen"));//通過構(gòu)造函數(shù)構(gòu)造新對象
var gl = from p in PersonList group p by p.age into x select x;//使用into子句創(chuàng)建標(biāo)識
foreach (var element in gl)//遍歷集合
{
foreach (Person p in element)//遍歷集合
{
Console.WriteLine(p.name.ToString());//輸出對象
}
}
Console.ReadKey();
}  上述代碼通過使用into子句創(chuàng)建標(biāo)識,從LINQ查詢語句中可以看出,查詢后返回的是一個集合變量x而不是p,但是編譯能夠通過并且能夠執(zhí)行查詢,這說明LINQ查詢語句將查詢的結(jié)果填充到了臨時標(biāo)識符對象x中并返回查詢集合給gl集合變量,運行結(jié)果如圖 14所示。
圖 14 into子句
注意:into子句必須以select、group等子句作為結(jié)尾子句,否則會拋出異常。 7 join連接子句
在數(shù)據(jù)庫的結(jié)構(gòu)中,通常表與表之間有著不同的聯(lián)系,這些聯(lián)系決定了表與表之間的依賴關(guān)系。在LINQ中同樣也可以使用join子句對有關(guān)系的數(shù)據(jù)源或數(shù)據(jù)對象進(jìn)行查詢,但首先這兩個數(shù)據(jù)源必須要有一定的聯(lián)系,示例代碼如下所示。    public class Person//描述“人”對象
{
public int age; //描述“年齡”字段
public string name;//描述“姓名”字段
public string cid;//描述“車ID”字段
public Person(int age,string name,int cid)//構(gòu)造函數(shù)
{
this.age = age;//初始化
this.name = name;//初始化
this.cid = cid;
}
}
public class CarInformaion//描述“車”對象
{
public int cid; //描述“車ID”字段
public string type; //描述“車類型”字段
public CarInformaion(int cid,string type)//初始化構(gòu)造函數(shù)
{
this.cid = cid;初始化
this.type = type; //初始化
}
}  上述代碼創(chuàng)建了兩個類,這兩個類分別用來描述“人”這個對象和“車”這個對象,CarInformation對象可以用來描述車的編號以及車的類型,而Person類可以用來描述人購買了哪個牌子的車,這就確定了這兩個類之間的依賴關(guān)系。而在對象描述中,如果將CarInformation類的屬性和字段放置到Person類的屬性中,會導(dǎo)致類設(shè)計臃腫,同時也沒有很好的描述該對象。對象創(chuàng)建完畢就可以使用List類創(chuàng)建對象,示例代碼如下所示。            List<Person> PersonList = new List<Person>(); //創(chuàng)建List類
PersonList.Add(new Person(21, "limusha",1));//購買車ID為1的人
PersonList.Add(new Person(21, "guojing",2)); //購買車ID為2的人
PersonList.Add(new Person(22, "wujunmin",3)); //購買車ID為3的人
List<CarInformaion> CarList = new List<CarInformaion>();
CarList.Add(1, "寶馬");//車ID為1的基本信息
CarList.Add(2, "奇瑞");  上述代碼分別使用了List類進(jìn)行對象的初始化,使用join子句就能夠進(jìn)行不同數(shù)據(jù)源中數(shù)據(jù)關(guān)聯(lián)的操作和外連接,示例代碼如下所示。        static void Main(string[] args)
{
List<Person> PersonList = new List<Person>();//創(chuàng)建List類
PersonList.Add(new Person(21, "limusha",1));//購買車ID為1的人
PersonList.Add(new Person(21, "guojing",2)); //購買車ID為2的人
PersonList.Add(new Person(22, "wujunmin",3));//購買車ID為3的人
List<CarInformaion> CarList = new List<CarInformaion>();//創(chuàng)建List類
CarList.Add(new CarInformaion(1,"寶馬"));//車ID為1的車
CarList.Add(new CarInformaion(2, "奇瑞"));//車ID為2的車
var gl = from p in PersonList join car in CarList on p.cid equals car.cid select p;//使用join子句
foreach (var element in gl)//遍歷集合
{
Console.WriteLine(element.name.ToString());//輸出對象
}
Console.ReadKey();
}  上述代碼使用join子句進(jìn)行不同數(shù)據(jù)源之間關(guān)系的創(chuàng)建,其用法同SQL查詢語句中的INNER JOIN查詢語句相似,運行后如圖 15所示。
圖 15 join查詢子句
8 let臨時表達(dá)式子句
在LINQ查詢語句中,let關(guān)鍵字可以看作是在表達(dá)式中創(chuàng)建了一個臨時的變量用于保存表達(dá)式的結(jié)果,但是let子句指定的范圍變量的值只能通過初始化操作進(jìn)行賦值,一旦初始化之后就無法再次進(jìn)行更改操作。示例代碼如下所示。
static void Main(string[] args)
{
List<Person> PersonList = new List<Person>();//創(chuàng)建List類
PersonList.Add(new Person(21, "limusha",1)); //購買車ID為1的人
PersonList.Add(new Person(21, "guojing",2)); //購買車ID為2的人
PersonList.Add(new Person(22, "wujunmin",3));//購買車ID為3的人
List<CarInformaion> CarList = new List<CarInformaion>();//創(chuàng)建List類
CarList.Add(new CarInformaion(1,"寶馬"));//車ID為1的車
CarList.Add(new CarInformaion(2, "奇瑞"));//車ID為2的車
var gl = from p in PersonList let car = from c in CarList select c.cid select p;//使用let 語句
foreach (var element in gl)//遍歷集合
{
Console.WriteLine(element.name.ToString());//輸出對象
}
Console.ReadKey();
}  let就相當(dāng)于是一個中轉(zhuǎn)變量,用于臨時存儲表達(dá)式的值,在LINQ查詢語句中,其中的某些過程的值可以通過let進(jìn)行保存。而簡單的說,let就是臨時變量,如x=1+1、y=x+2這樣,其中x就相當(dāng)于是一個let變量,上述代碼運行后如圖 16所示。
圖 16 let子句
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
LINQ中的一些查詢語句格式
oracle forall 介紹
Linq to SQL 的更新沖突與管理 - 陀螺的日志 - 網(wǎng)易博客
LinQ基本使用:查詢數(shù)組
SQL是功能強大的數(shù)據(jù)庫語言,其實SQL很簡單,你也可以輕松學(xué)會
12.1 更新表中的數(shù)據(jù) - 《精通SQL——結(jié)構(gòu)化查詢語言詳解》 - 免費試讀 - bo...
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服