前言html
最先使用到Lambda表達式是由於一個需求:
若是一個數組是:int[] s = new int[]{1,3,5,9,14,16,22};
例如只想要這個數組中小於15的元素而後從新組裝成一個數組或者直接讓s返回一個新數組該怎麼截取?數據庫
最開始的想法就是將這個s遍歷一遍而後判斷下再來從新組裝成新的數組.好麻煩是否是? 因而便百度到了一個叫作Lambda的東西, 因此用了以後效果以下:編程
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 int[] s = new int []{ 1,3,5,9,14,16,22 }; 6 var result = from n in s where n < 15 select n; 7 int[] b = result.ToArray(); 8 for (int i = 0; i < b.Length; i++) 9 {10 Console.WriteLine(b[i]);11 }12 Console.ReadKey();13 }14 }
打印結果如咱們所想: 1, 3, 5, 9, 14.數組
剩下的就是在真實的項目中接觸到的, 在這裏只是做爲舉例, 不作細緻講解: 微信
1 var splitTexts = cmbValidationText.Split(new string[] { IncidentConstant.Comma },
StringSplitOptions.RemoveEmptyEntries); 2 if (cmbValidation.Items != null && cmbValidation.Items.Count > 0) 3 { 4 foreach (var splitText in splitTexts) 5 { 6 bool valid = cmbValidation.Items.Any(item => (item != null) && (item.Enabled) &&
(string.Equals(splitText, item.Prefix, StringComparison.OrdinalIgnoreCase))); 7 8 if (!valid) 9 {10 invalidText += splitText.ToString() + CommaAndBlank;11 isInvalidTextExist = true;12 }13 }14 }15 16 var categoryAndCapabilities = capabilities.Select(item =>17 {18 PRResponseCategory category = null;19 PRCapability prCapability = provisioningManager.GetPRCapabilityByKey(item.PRCapabilityKey.
GetValueOrDefault());20 if (prCapability != null)21 {22 category = statusMonitorDao.GetResponseCategoryByKey(prCapability.ResponseCategoryKey.
GetValueOrDefault());23 }24 return new { Category = category, PRCapability = prCapability, Capability = item };25 })26 .Where(item => (item != null && item.Category != null && item.PRCapability != null))27 .OrderBy(item => item.Category.Code)28 .ThenBy(item => item.PRCapability.AllowNumeric.GetValueOrDefault() ? 1 : 0)29 .ThenBy(item => item.PRCapability.CapabilityCode)30 .GroupBy(item => item.PRCapability.ResponseCategoryKey.GetValueOrDefault())31 .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());
這裏會不會以爲很神奇? 那麼下面就開始Lambda及Linq之旅吧.ide
1,Linq解析
Linq是Language Integrated Query的縮寫, 即"語言集成查詢"的意思. 它主要包含4個組件: Linq to Object, Linq to XML, Linq to DataSet 和Linq to Sql.
更多詳細內容能夠查看一個國外網站: http://www.dotnetperls.com/linq函數
下面步入正題:post
(1),查詢表達式學習
查詢表達式是一種使用查詢語法表示的表達式,它用於查詢和轉換來自任意支持LINQ的數據源中的數據。查詢表達式使用許多常見的C#語言構造,易讀簡潔,容易掌握。它由一組相似於SQL或XQuery的聲明性語法編寫的子句組成。每個子句能夠包含一個或多個C#表達式。這些C#表達式自己也多是查詢表達式或包含查詢表達式。網站
查詢表達式必須以from子句開頭,以select或group子句結束。第一個from子句和最後一個select子句或group子句之間,能夠包含一個活多個where子句、let子句、join子 句、orderby子句和group子句,甚至還能夠是from子句。它包括8個基本子句,具體說明以下所示。
●from子句:指定查詢操做的數據源和範圍變量。
●select子句:指定查詢結果的類型和表現形式。
●where子句:指定篩選元素的邏輯條件。
●let子句:引入用來臨時保存查詢表達式中的字表達式結果的範圍變量。
●orderby子句:對查詢結果進行排序操做,包括升序和降序。
●group子句:對查詢結果進行分組。
●into子句:提供一個臨時標識符。join子句、group子句或select子句能夠經過該標識符引用查詢操做中的中堅結果。
●join子句:鏈接多個用於查詢操做的數據源。
1.1,select,from, where子句:
示例1
下面建立一個查詢表達式query,該查詢表達式查詢arr數組中的每個元素。
int[]arr =new int[]{0,1,2,3,4,5,6,7,8,9};
分析1
View Code
示例2
下面建立一個查詢表達式query2.該查詢表達式查詢arr數組中大於6的元素。
View Code
分析2
變量只是保存查詢操做,而不是查詢的結果。當查詢表達式執行查詢操做時,纔會計算該查詢表達式的結果。以上兩個變量的類型都屬於集合類型。
示例3
下面建立一個查詢表達式query。該查詢表達式包含兩個from子句,他們分別查詢兩個獨立的數據源;arr1數組和arr2數組。最後,使用select子句計算當前元素的和。
View Code
分析3
包含符合from子句的查詢表達式
在查詢表達式中,有可能查詢表達式的數據源中的每個元素自己也做爲該查詢表達式的數據源。那麼要查詢數據源中的每個元素中的元素,則須要使用符合from子句。符合from子句相似於嵌套的foreach語句。
1.2,let子句
let子句用來建立一個新的範圍變量,它用於存儲子表達式的結果。let子句使用編程者提供的表達式的結果初始化該變量。一旦初始化了該範圍變量的值,它就不能用於存儲其餘的值。
示例
下面建立一個查詢表達式query。該查詢表達式從arr數組中查詢爲偶數的元素。
View Code
分析
"return n%2==0?true:false"表達式判斷n元素是否爲偶數。若是是,則返回true,不然返回false。「let isEven =return n%2==0?true:false」表達式使用let子句建立新的範圍變量isEven,用來保存"return n%2==0?true:false"表達式的結果。"where isEven"表達式使用where子句篩選isEven的值爲true的元素。
1.3,orderby子句
orderby子句可以使返回的查詢結果按升序或者降序排序。升序由關鍵字ascending指定,而降序由關鍵字descending指定。
注意:orderby子句默認排序方式爲升序。
示例
下面建立一個查詢表達式query。該查詢表達式從arr數組中查詢大於1且小於6的元素,而且按照n元素對查詢結果進行降序排序。
View Code
分析
orderby子句能夠包含一個或多個排序表達式,各個排序表達式使用逗號(,)分隔。
1.4, group子句
group子句用來將查詢結果分組,並返回一對象序列。這些對象包含零個或更多個與改組的key值匹配的項,還可使用group子句結束查詢表達式。
注意:每個分組都不是單個元素,而是一個序列(也屬於集合)。
示例
下面建立一個查詢表達式query。該查詢表達式從arr數組中查詢大於1且小於6的元素,而且按照n%2表達式的值對查詢結果進行分組。
View Code
分析
query查詢表達式的結果是一個序列(類型爲IEnumerable<IGrouping<int,int>>),該序列的元素類型爲IGrouping<int,int>.其實,該查詢結果中的元素也是一個序列。
1.5, into子句
下面建立一個查詢表達式query。該查詢表達式從arr數組中查詢大於1且小於6的元素,而且按照n%2表達式的值對查詢結果進行分組。該查詢表達式的具體說明以下所示:
where n>1 && n<6:指定篩選大於1且小於6的元素。
group n by n%2 into g: 按照n%2表達式的值對查詢結果進行分組(0和0一組, 1和1 一組),並使用into子句建立臨時標識符g。該臨時標識符臨時保存分組結果。
from sn in g:從g標識符指定的每個分組中查詢sn元素。
select sn:表示查詢sn元素。
View Code
分析
上述查詢表達式的查詢結果包括4個元素,依次爲二、四、3和5
1.6, join子句
oin子句用來鏈接兩個數據源,即設置兩個數據源之間的關係。join子句支持如下3種常見聯接方式。
內部聯接:元素的連接關係 必須同時知足兩個數據源,相似於SQL語句中的inner join子句。
分組聯接:包含into子句的join子句。
左外部聯接:元素的連接關係必須知足聯接中的左數據源,相似於SQL語句中的left join子句。
內部聯接:join子句的內部聯接要求兩個數據源都必須存在相同的值,即兩個數據源都必須存在知足聯接關係的元素。
示例
下面建立一個查詢表達式query。該查詢表達式使用join子句聯接了arra和arrb數組,具體說明以下。
建立arra數組,它包含10個元素(0~9)。
建立arrb數組,它包含5個元素(0、二、四、6和8)。
建立query查詢。
from a in arra:從arra數組中選擇元素,並表示爲a。
where a < 7: 從arra數組中選擇小於7的元素
join b in arrb on a equals b: 將arra和arrb數組進行聯接,同時知足a和b相等的條件。其中,b元素是arrb數組中的元素。
select a: 選擇a元素。
View Code
分析
上述查詢表達式首先選擇小於7的元素,(包括0~6),而後再喝arrb數組進行聯接,並獲取既包含在{0,1,2,3,4,5,6}集合中,又包含在arrb數組中的元素。最終,查詢表達式的結果包含4個元素(0、二、4和6)
分組聯接:join子句的分組聯接包含into子句的join子句的連接。它將左數據源與右數據源的元素一次匹配。左數據源的全部元素都出如今查詢結果中。若在右數據源中找到匹配項,則使用匹配的數據,不然用空表示。
(2),使用Linq to XML查詢XML文件
在Linq提出以前, 咱們可使用XPath來查詢XML文件, 可是用XPath時必須首先知道XML文件的具體結構, 而使用Linq to XML則不須要知道這些.
並且Linq to XML的代碼還更加簡潔.
View Code
Linq to DataSet其實都和Linq to Object 相似, 這裏就不在講解了.更多內容在如下兩個連接:
MSDN之Linq講解
Linq操做合集
2,Lambda表達式
Lambda表達式能夠理解爲一個匿名方法, 它能夠包含表達式和語句, 而且用於建立委託或轉換表達式樹.
在使用Lambda表示式時, 都會使用"=>"運算符(讀做goes to), 該運算符的左邊是匿名方法的輸入參數, 右邊則是表達式或語句塊.
這裏主要列舉下Linq和Lambda表達式的一些區別:
LINQ的書寫格式以下:
from 臨時變量 in 集合對象或數據庫對象
where 條件表達式
[order by條件]
select 臨時變量中被查詢的值
[group by 條件]
Lambda表達式的書寫格式以下:
(參數列表) => 表達式或者語句塊
其中:參數個數:能夠有多個參數,一個參數,或者無參數。
參數類型:能夠隱式或者顯式定義。
表達式或者語句塊:這部分就是咱們日常寫函數的實現部分(函數體)。
1.查詢所有
查詢Student表的全部記錄。
View Code
2 按條件查詢所有:
查詢Student表中的全部記錄的Sname、Ssex和Class列。
View Code
3.distinct 去掉重複的
查詢教師全部的單位即不重複的Depart列。
View Code
4.鏈接查詢 between and
查詢Score表中成績在60到80之間的全部記錄。
View Code
5.在範圍內篩選 In
View Code
6.or 條件過濾
查詢Student表中"95031"班或性別爲"女"的同窗記錄。
View Code
7.排序
以Class降序查詢Student表的全部記錄。
View Code
8.count()行數查詢
View Code
9.avg()平均
查詢'3-105'號課程的平均分。
View Code
10.子查詢
查詢Score表中的最高分的學生學號和課程號。
View Code
11.分組 過濾
查詢Score表中至少有5名學生選修的並以3開頭的課程的平均分數。
View Code
12.分組
查詢Score表中至少有5名學生選修的並以3開頭的課程的平均分數。
View Code
13. 多表查詢
View Code
14,關聯多條件查詢
感謝@浪子哥 給的建議, 如今加上兩張表的關聯多條件查詢, 只有Linq和Lambda表達式
今天本身又參考園裏大神的一些帖子本身寫了一個兩張表關聯查詢的Linq及Lambda表達式的Demo, 你們能夠看下.
DataTable tableA = tableA.Columns.Add(, ( tableA.Columns.Add(, ( tableA.Columns.Add(, ( DataTable tableB = tableB.Columns.Add(, ( tableB.Columns.Add(, ( tableB.Columns.Add(, ( tableA.Rows.Add(, , tableA.Rows.Add(, , tableA.Rows.Add(, , tableA.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , tableB.Rows.Add(, , singleQuery = tableA.AsEnumerable().Where(stu => stu.Field<>() > ( item Console.WriteLine(, item.Field<>(), item.Field<>( doubleQuery = a b a.Field<>() == b.Field<>() && a.Field<>() != b.Field<>( a.Field<>(), a.Field<>( Name = a.Field<>( A_Age = a.Field<>( B_Age = b.Field<>( ( item Console.WriteLine( query = a => a.Field<>( b => b.Field<>( (a, b) => a = b = .Where(c => (c.a.Field<>() != c.b.Field<>( .OrderBy(d => d.a.Field<>( .ThenBy(e => e.a.Field<>( .Select(f => Name = f.a.Field<>( A_Age = f.a.Field<>( B_Age = f.b.Field<>( A_Score = f.a.Field<>( B_Score = f.a.Field<>( ( item Console.WriteLine(
73 }74 Console.ReadKey();75 }76 }
解析:
首先能夠看出來, Lambda表達式對於這種多表多條件的查詢寫法的易讀性明顯沒有Linq高, 因此 仍是建議用Linq去寫. 運行結果以下圖: