嘿嘿,說起來ORM和LinQ,就感覺離我好遙遠的,在學校是沒有學習的,所以總感覺學習了LinQ就是大神,現在嘛,終於也體會一點,感覺LinQ只是初步學習,沒有太難,當然以后使用在項目中就沒有這樣的簡單啦,下面就全面的總結一下LinQ的其中一部分,LinQ有三部分:LinQ TO Object;LinQ TO SQL ;LinQ TO XML。而在這里我先來總結一下LinQ TO Object的學習吧
一.初步認識LinQ to Object
static void Main(string[] args) {//一個簡單認識LinQ的小例子: int[] array = {1,2,3,4,5,6,7 }; //相當於數據源 IEnumerable<int> everyarray = from n in array //定義並存儲查詢 where n > 3 select n; foreach (var item in everyarray) //執行查詢 { Console.WriteLine(item); } Console.ReadKey(); }
在主句庫中我們可以看到一張張的表存放數據,而在程序中卻與數據庫相反,保存在類對象或者結構中的數據差異很大,因此沒有通用的查詢語句來從數據結構中獲取數據,從對象獲取數據的方法在這里我們就可以使用LinQ,可以輕松的查詢對相集合。LinQ:語言集成查詢,是.net框架的擴展,允許我們使用SQL查詢數據庫的方式來查詢數據集合,使用LinQ可以從數據庫,程序對象的集合以及XML文檔中查詢數據.
二.匿名類型
匿名類型就是創建無名類類型的特性,匿名類型經常用於LinQ查詢的結果之中,創建匿名類型沒有類名和構造函數,下面就演示一下匿名類型的對象創建表達式:
var student = new {Name="下雨天",Age=20,Major="asp.net" }; //匿名對象初始化 在這里需要使用關鍵字var,強類型 Console.WriteLine("{0},年齡:{1}、主修課程:{2}",student.Name,student.Age,student.Major); Console.ReadKey();
匿名類型注意事項:
匿名類型只能和局部變量配合使用,不能用於類成員
匿名樂行沒有名字,必須使用var關鍵字做為變量類型
不能設置匿名類型對象的屬性,而且編譯器為匿名類型創建的屬性是只讀的
三.查詢語法和方法語法
LinQ查詢時可以使用兩種形式的語法:查詢語法和方法語法。
static void Main(string[] args) { int[] array = {2,3,4,56,73,4,23,34 }; var nums = from n in array //查詢語法,看上去和SQL很像,使用查詢表達式語法書寫 where n > 10 select n; var num = array.Where(x=>x>10); //方法語法,使用標准的方法調用 int arr = (from n in array where n > 10 select n).Count(); //兩種形式的組合 foreach (var item in nums) { Console.WriteLine(item); } foreach (var item in num) { Console.WriteLine(item); } Console.WriteLine(arr); Console.ReadKey(); }
查詢語法是聲明式的,看上去和SQL語句很相似,查詢語法使用查詢表達式書寫;而方法語法是命令式的,使用的是標准的方法調用,方法十一組交租標准查詢運算符的方法。
四.查詢變量
LinQ查詢時間可以返回兩種結果,一個是枚舉,另一個是標量;枚舉列表滿足查詢參數的項列表;標量滿足查詢條件的結果的某種摘要形式。
static void Main(string[] args) { int[] array = {1,2,3,4,5,6,7,8,9 }; IEnumerable<int> intlist = from n in array //返回枚舉數 where n < 6 select n; int nums = (from n in array //返回一個整數 where n > 5 select n).Count(); foreach (var item in intlist) { Console.WriteLine(item); } Console.WriteLine(nums); Console.ReadKey(); }
如果查詢表達式返回枚舉,查詢一直到處理枚舉時間才會被執行,如果枚舉被處理多次,查詢就會被執行多次;如果查詢表達式返回標量,查詢立即執行,並且把結果保存在查詢變量中。
五.查詢表達式的結構
查詢表達式子句必須按照一定的順序出現,from子句select……group子句這兩部分是必需的,其他可選;可以有任意多的from……let……where子句。
1.from子句
static void Main(string[] args) { int[] array = {10,23,33,44 }; IEnumerable<int> fromlist = from item in array //item為迭代變量 where item < 30 //使用迭代變量 select item; //使用迭代變量 foreach (var item in fromlist) { Console.WriteLine(item); } Console.ReadKey(); }
from子句,指定了要作為數據源使用的數據集合,它還引入了迭代矢量,迭代變量逐個表示數據源的每一個元素。Type時是集合元素的類型,這個可選,因為編譯器可以從集合中推斷類型。Item是迭代器的名字,Items是要查詢的集合的名字,集合必須是可枚舉類型,即:from type Item in Items。
在這里需要注意的是:from子句和foreach語句很相似,但是還是有區別的:1.foreach語句命令式的指定了要從第一個到最后一個按照順序的訪問集合中的項,而from子句則聲明似的規定集合中的每個=項都需要被訪問,但沒有假定以什么順序;2.foreach語句在遇到代碼時就執行某主體,而from子句不執行,它創建可查詢的后台代碼對象。只有在程序的控制流遇到訪問查詢變量的語句時,才會執行查詢。
2.join子句以及什么是聯結
LinQ中的join子句和SQL中的JOIN子句很相似, LinQ接受兩個集合然后創建一個新的集合,每個元素包含兩個原始集合中的原始成員。而join用來聯結兩個集合,下面就了解下聯結:
public class Student //初始化數組 { public int sId; public string LastName; } public class Course { public int cId; public string CourseName; } static Student[] student = new Student[]{ //初始化數組 new Student{LastName="下雨天",sId=1}, new Student{LastName="晴天娃娃",sId=2}, new Student{LastName="旋轉音樂盒",sId=3}, }; static Course[] course = new Course[]{ new Course{CourseName="asp.net",cId=1}, new Course{CourseName="java",cId=1}, new Course{CourseName="Linux",cId=2} }; static void Main(string[] args) { var querylist = from s in student //student是第一個集合course是第二個集合, join c in course on s.sId equals c.cId // sId是第一個集合的項,cId是第二個集合的項 where s.LastName == "下雨天" //在這里即使用了join子句,也可以看出來聯結的語句結構 select c.CourseName; foreach (var item in querylist) { Console.WriteLine(item); } Console.ReadKey(); }
使用聯結來結合兩個或更多集合中的數據,聯結操作結合兩個集合然后創建一個臨時的對象集合,每一個對象都包含原始集合中的所有字段;在這里需要注意的是,要使用關鍵字equals,而不能使用“==”運算符。
3.查詢主體中的from…let…where
(1)from子句:第一個from子句是查詢表達式必需的子句,第二個from子句是第一個子句的查詢主體。
static void Main(string[] args) { var groupa = new[] { 3, 4, 5, 6 }; var groupb = new[] { 6, 7, 8, 9 }; var nums = from a in groupa //必需第一個from子句 from b in groupb //查詢主體的第二個from子句 where a > 4 && b <= 8 select new { a, b, sum = a + b }; //匿名類型對象 foreach (var item in nums) { Console.WriteLine(item); } Console.ReadKey(); }
在這里select子句創建了一個匿名類型的對象。
(2)let子句:let接受一個表達式的運算並且把他賦值給一個需要在其他運算中使用的標示符。
static void Main(string[] args) { var groupa = new[] { 3, 4, 5, 6 }; var groupb = new[] { 6, 7, 8, 9 }; var num = from a in groupa //必需第一個from子句 from b in groupb //查詢主體的第二個from子句 let sum = a + b //在新的變量中保持結果 where sum == 12 select new { a, b, sum }; foreach (var item in num) { Console.WriteLine(item); } Console.ReadKey(); }
(3)Where子句:where子句根據之后的運算來去除不符合指定條件的項
static void Main(string[] args) { var groupa = new[] { 3, 4, 5, 6 }; var groupb = new[] { 6, 7, 8, 9 }; var list = from a in groupa from b in groupb let sum = a + b where sum >= 12 where a == 4 select new { a, b, sum }; foreach (var item in list) { Console.WriteLine(item); } Console.ReadKey(); }
需要注意的是:只要是在from……let……where部分中,查詢表達式可以有任意多個where子句,一個項必須滿足where子句才能在之后被過濾。
(4)Orderby子句:order子句接受一個表達式並根據表達式按照順序返回結果項
static void Main(string[] args) { var student = new[] { new {FirstName="張",LastName="三",Age=16,Major="asp.net"}, new {FirstName="李",LastName="四",Age=19,Major="java"}, new {FirstName="王",LastName="五",Age=20,Major="php"} }; var query = from s in student orderby s.Age //根據age排序 select s; foreach (var s in query) { Console.WriteLine("{0}{1}:{2},主修:{3}", s.FirstName, s.LastName, s.Age, s.Major); } Console.ReadKey(); }
在這里,可選的ascending和descending關鍵字設置了排序方向,orderby子句的默認排序是升序。我們可以使用ascending和descending關鍵字顯式的設置元素的拍訊為升序或者降序,可以有多個任意子句,使用逗號隔開即可。
(5)Select子句:制定所選對象的那部分應該被select。它可以指定:整個數據項,整個項的一個字段,數據項中整個字段組成的新對象。
static void Main(string[] args) { var student = new[] { //匿名類型的對象數組 new {FirstName="張",LastName="三",Age=16,Major="asp.net"}, new {FirstName="李",LastName="四",Age=17,Major="java"}, new {FirstName="王",LastName="五",Age=20,Major="php"} }; var query = from s in student select s; foreach (var item in query) { Console.WriteLine(item); } Console.ReadKey(); }
(6)查詢中的匿名類型:查詢結果中可以由原始集合的項,項的某些字段或匿名類型組成,然后如下所示:
static void Main(string[] args) { var student = new[] { //匿名類型的對象數組 new {FirstName="張",LastName="三",Age=16,Major="asp.net"}, new {FirstName="李",LastName="四",Age=17,Major="java"}, new {FirstName="王",LastName="五",Age=20,Major="php"} }; var query = from s in student select new { s.FirstName, s.LastName, s.Major };//創建匿名類型 foreach (var s in query) { Console.WriteLine("{0}{1}:{2}", s.FirstName, s.LastName, s.Major); } Console.ReadKey(); }
(7)Group子句:group子句把select的對象根據一些標准進行分組。
static void Main(string[] args) { var student = new[] { //匿名類型的對象數組 new {FirstName="張",LastName="三",Age=16,Major="asp.net"}, new {FirstName="李",LastName="四",Age=16,Major="java"}, new {FirstName="王",LastName="五",Age=20,Major="php"} }; var query = from s in student group s by s.Age; foreach (var s in query) //枚舉分組 { Console.WriteLine("{0}", s.Key); foreach (var item in s) { Console.WriteLine(" {0}{1}", item.FirstName, item.LastName); } } Console.ReadKey(); }
注意的事項主要有:如果項包含在查詢的結果中,他們就可以根據某個字段的值進行分組,作為分組依據的屬性叫做鍵;group子句返回的不是原始數據源中項的枚舉,而是返回可以枚舉已經形成的項的分組的可枚舉類型;分組本身如果是可枚舉類型,他們可以枚舉實際的項。
查詢表達式返回的對象是從查詢中枚舉分組結果的可枚舉類型,每一個分組由一個叫做鍵的字段區分,每一個分組本身是可枚舉類型,他們可以枚舉實際的項。
(8)查詢延續。into子句:查詢延續可以接受查詢的一部分結果並賦予一個名字,從而可以再查找的另一部分中使用
static void Main(string[] args) { var groupa = new[] { 7, 4, 5, 6 }; var groupb = new[] { 6, 7, 8, 9 }; var query = from a in groupa join b in groupb on a equals b into groupc from c in groupc select c; foreach (var item in query) { Console.WriteLine(item); } Console.ReadKey(); }
(9).標准查詢運算符:這個共有40多個方法,簡單的方法已經在昨天舉例寫過,這里就添加一個連接(http://www.cnblogs.com/dyxd/p/4187916.html),不再總結啦。寫一下具體的分類:
六.查詢表達式和標准查詢運算符
var num = new int[] {3,6,4,8,10 }; int numbers = (from n in num where n < 7 //查詢表達式 select n).Count(); //運算符 Console.WriteLine("數量:{0}",numbers); Console.ReadKey();
標准查詢運算符是進行查詢的一組方法,每一個查詢表達式還可以使用帶標准查詢運算符的方法的語法來編寫。編譯器把每一個查詢表達式翻譯成標准查詢運算符的形式,由於所有查詢表達式都被翻譯成標准查詢運算符,因此運算符可以執行由查詢表達式完成的任何操作,而且所有查詢表達式形式所不能提供的附加功能。當然,查詢表達式和方法語法這兩種表達式也可以組合。
在這里還有委托作為參數以及LinQ預定義的委托類型,Lambda表達是參數在昨天已經總結過啦,嘿嘿,所以關於LinQ to Object就總結到這里,我總結的僅僅是初學者都能看懂的,還沒有在項目中使用目前,希望以后在項目中使用時間我能夠熟練的運用。