LINQ學習心得分享--------(一)LINQ簡介和基礎學習
這一節主要向大家講三個問題,第一個問題什么是LINQ,第二個問題LINQ主要解決什么問題,第三個問題學習LINQ需要做哪些基本的准備。
首先第一個問題,什么是LINQ?LINQ中文翻譯為語言集成查詢(Language Integrated Query),更通俗的講,它相當於一個通用的數據查詢接口。LINQ最初由Anders hejlsberg構思,2007年11月19日,LINQ作為.NET FrameWork3.5的一部分正式發布,同時微軟也將LINQ集成到了Visual Studio 2008中,這一巨大的創新,實現了面向對象和數據訪問的互通有無。
第二個問題,LINQ主要解決什么問題?也就是LINQ的設計目的。我們知道在LINQ之前,面向對象和數據訪問這兩個領域是相互分裂的,編程語言中的數據類型,和數據庫中的數據類型也有一些出入,同時SQL和XML都有自己的查詢語言而對象卻沒有自己的查詢語言,這些在很大程度上限制開發的效率,而LINQ的設計理念就是在不同類型的數據之間(關系數據、層次模型數據等)之間實現數據訪問的互通有無,為不同的數據類型提供統一的訪問接口。具體體現為LINQ主要包含了以下三大部分: LINQ to Objects主要負責對象的查詢,LINQ to XML 主要負責XML的查詢, LINQ to ADO.NET 主要負責數據庫的查詢,而LINQ to ADO.NET又包括 LINQ to SQL,LINQ to DataSet,LINQ to Entrties這三部分。這樣就很好的符合了其設計理念,實現了對不同類型的數據訪問。
第三個問題,LINQ學習需要做哪些准備?也就是需要掌握哪些前期的基礎知識。在開始學習LINQ之前,我們需要先來了解下理解C# 3.0的一些新特性:隱含類型局部變量、自動屬性、對象初始化器、集合初始化器、匿名類型、Lambda表達式、擴展方法、局部方法、yield和IEnumerable接口、查詢句法。
下面我會通過做一些小例子,把這些特性一一給大家講解一下。
1、隱含類型的局部變量。
學過Javascript的朋友相信對var這個關鍵字肯定一點也不陌生,我們都知道Javascript是一種弱類型的語言,所以在運行的時候才會更加的靈活。我們現在所接觸的語言大部分都是強類型的語言,所謂強類型的語言,就是程序聲明的變量、實例化對象,必須有明確的類型規定,這樣在編譯的時候就為其分配一定的內存空間,這樣的話代碼的安全的安全性就比較高,弱類型的語言比較靈活,但是它也比較容易出錯也是其詬病之一。為了提高程序的運行效率和靈活性,微軟也把var給引進了進來。看下面的例子:
private static void UnknowName()
{
var name = "Olive";
var age = 22;
var address = "北京";
var Frieds = new[] { "Olive", "MoYao", "Momo" };
Console.WriteLine("名字為:"+name);
Console.WriteLine("年齡:" + age * 2);
foreach (var f in Frieds)
{
Console.WriteLine(f);
}
Console.ReadKey();
}
實驗結果:
調試時,編譯器自動識別數據類型:
運行結果:
由實驗結果可知:編譯器可以自動識別隱含類型的局部變量,但是前提是變量必須有值,在這里值可以為null,但是在使用null之前,必須要確定類型,例如:var test=(string)null;這樣編譯器可以自動的推斷值類型,如果單純的為test=null,則編譯器無法識別其類型。
2、自動屬性
直接看下面代碼:
在C#3.0以前創建一個類:
Class Person{
private string name;
private string sex;
private int age;
public string Name
{
get{ return name; }
set{name = value;}
}
public string Sex
{
get { return sex;}
set { sex = value;}
}
public int Age
{
get{ return age;}
set{ age = value;}
}
}
在C#3.0以后可以這樣寫,相當於一個語法糖,省了很多代碼,效果是一樣的。
public class Person
{
public string Name
{
get;
set;
}
public string Sex
{
get;
set;
}
public int Age
{
get;
set;
}
}
3、對象初始化器
在這里還是用上邊的例子,在C#3.0以前可以這樣初始化對象
Person p=new Person();
p.Name="Olive";
p.Sex="女";
p.Age=22;
在C#3.0以后可以這樣初始化
Person p=new Person(){ Name="Olive",Sex="女",Age=22};
4、集合初始化器
還是上邊的例子:
C#3.0之前
List<Person> list=new List<Person>();
Person p=new Person();
p.Name="Olive";
p.Sex="女";
p.Age=22;
Person p1=new Person();
P1.Name="Moyao";
P1.Sex="男";
P1.Age=23;
list.add(p);
list.add(p1);
C#3.0之后
List<Person> list=new List<Person>()
{
new Person(){ Name="Olive",Sex="女",Age=22},
new Person(){ Name="Moyao",Sex="男",Age=23}
};
5、匿名類型
和隱含類型的局部變量一樣,匿名類型就是開發者自定義類型,無須顯示定義。在LINQ中匿名類會常常用到。
Var name="Olive";
Var sex="女";
Var age=22;
Var person=new{ Name=name,Sex=sex,Age=age};
Consol.WriteLine("名字:"+person.Name"+"性別:"+person.Sex+"年齡:"+person.Age);
實驗結果:
6、Lambda表達式
在講Lambda表達式之前先講一下委托,和匿名函數。事實上Lambda表達式是由委托——》匿名函數——》Lambda表達式一步步過渡而來的。
6.1委托:
聲明委托: public delegate string ShowLove(string name);
委托調用函數:private static string ShowMyLove(string name)
{
return "I Love you " + name;
}
//在主函數里調用該函數,參數為一個委托對象
private static string Show(ShowLove showLove)
{
string love = showLove("Olive");
return love;
}
結果為:
6.2 在2.0中的匿名函數:
這個時候可以將上邊的Show方法寫成這樣
Private string Show(string name)
{
Delegate(string name)//匿名方法
{
Return "I Love you " +name;
}
}
匿名方法顧名思義就是沒有方法名,但是需要用delegate關鍵字修飾
6.3 Lambda表達式
事實上Lambda表達式和匿名方法差不多,都是用於產生內聯方法,但是Lambda表達式的語法更為簡潔。語法如下:
(參數列表) => 表達式或者語句塊
上邊的例子還可以這樣寫:
Private string Show((name)=>return "I Love you "+ name;);
產生的效果是一樣的。
Lambda表達式和匿名函數的區別在於,Lambda的參數可以不寫類型,匿名函數的參數類型必須得確定.
只有一個參數時小括號()和大括號{}可以省略不寫,
形如:Show(name=>return "I love you "+name");
同時如果執行的代碼只有一句話是關鍵字return、{}也可以省略形如:
Show(name=>"I love you "+name");
如果是需要執行多句話則{}不能省略,形如:
Show(name=>{ string love=name+"116";return love; });
但是如果沒有參數時,括號是萬不可省略的形如Show(()=>"I Love you");
7、擴展方法
擴展方法多用於對CLR類型進行一些操作的擴展,在3.0之前如果要實現這些操作,一般都是建一下輔助類,擴展方法,能方便的實現這些公共。
在開始做示例之前,先講些定義擴展方法需要注意的地方:
1、擴展方法只能在靜態類中定義並且是靜態方法,
2、擴展方法不能與原有方法名沖突,否則將無效
3、擴展方法的參數必須為(this 擴展類 類實例,Parameter p)
請看示例:比如要對string 類進行擴展
//String 的擴展類
public static class ExtensionString
{
public static string ShowLove(this string s)
{
return "I Love " + s;
}
}
調用:Console.WriteLine("Olive".ShowLove());
結果:
8、局部方法
談到局部方法,首先要說一下局部類,局部類是用Partial修飾的類,可以由多個partial修飾的同名類組合成一個類,局部方法是3.0以后加入的特性,局部方法必須定義在局部類中,但是局部方法的定義和實現可以分開。在這里同時也需要注意,局部的方法的返回值必須是靜態的返回值必須是void,可以有參也可以無參,有無方法實現均可。
下邊來看示例:
public partial class PartialTest
{
partial void Show(string name);
}
public partial class PartialTest
{
partial void Show(string name)
{
Console.WriteLine("名字:" + name);
}
}
在主函數中調用
PartialTest p=new PartialTest();
//p.Show();//這個時候你會發現對象p里根本沒有Show()方法,因為默認的Partial方法為私有方法,可能有人會想有private修飾一下,這個時候也不能這樣做,只需要它是私有的就可以了
那么該如何調用局部方法呢?
我們可以在對象的構造函數里進行調用:
以上的代碼做如下修改
public partial class PartialTest
{
PatrialTest( string name)
{
Show(sname);
}
partial void Show(string name)
{
Console.WriteLine("名字:" + name);
}
}
結果:
在這里需要注意的是局部函數是私有類型的,但是不能用Private來修飾,如果需要調用的話,可以在構造函數里進行調用。
9、yield關鍵字
我們知道如果想要能夠foreach遍歷的話,必須要實現IEnumerable接口,GetEnumerator()方法,而yield關鍵字是用來幫助IEnumerable對象自動生成一個輔助IEnumerator對象。但是yield關鍵字只能用在retur關鍵字或break關鍵字之前。
請看示例:(該示例引自Rookie_J博客)
(1)定義一個實現了接口IEnumerable的類MyYield:
class MyYield : IEnumerable { publicint StartCountdown; public IEnumerator GetEnumerator() { for (int i= StartCountdown; i>=0; i--) yieldreturn i;//yield自動生成一個實現了接口IEnumerator的類 }
}
(2)建立Myield類的對象,且通過foreach實現列舉功能:
MyYield myYield=new MyYield() { StartCountdown=10};foreach (int nin myYield) { Console.WriteLine(n); }
10、查詢語法。
學到這里,你基本上已經把學習LINQ的前期鋪墊給做好了,下面就來接觸下我們要學習的LINQ查詢語法吧。在這里只是做一個簡單的介紹,讓大家對此有個大致的了解,下一節我會具體的介紹LINQ的查詢語法。
還是以上邊創建的Person類為例:
List<Person> list = new List<Person>() { new Person() { Name = "Olive", Age = 22, Sex = "女" }, new Person() { Name = "Moyao", Age = 22, Sex = "男" } };
Var linqperson=from p in list where p.Name="Moyao" select p;
Foreach(Person p in linqperson)
{
Console.WriteLine(p.Name+"-----"+p.Age+"---p.Sex);
}
結果如下:
先做一個大概的解析LINQ語法形式:from in where select
SQL語法形式:select from where
是不是很像呢?
好吧,下一節我會慢慢給大家分享。