Entity Framework學習筆記(六)----使用Lambda查詢Entity Framework(1)

請註明轉載地址:http://www.cnblogs.com/arhat

在前幾章中,老魏一直使用Linq來查詢Entity Framework。可是老魏感受,若是使用Linq的話,那麼Linq的返回值類型有的時候不是很容易找出來,沒有直接使用Lambda來的直觀,至少在Lambda中咱們能夠指定返回的類型,這樣一來就能夠指定返回值了。express

在本章的開始呢,老魏先複習一下.NET提供的幾個經常使用的Lambda委託,而這些委託能夠說是常常又獲得的,尤爲實在IEnumerable<T>和 IQueryable<T>的擴展方法中常常的被用到。函數

經常使用委託:測試

1.封裝一個具備一個參數並返回 TResult 參數指定的類型值的方法。優化

public delegate TResult Func<in T, out TResult>(T arg)

這個委託有兩個類型參數,一個輸入參數和返回值:
in T:此委託封裝的方法的參數類型。
out TResult:此委託封裝的方法的返回值類型。
那麼這個委託怎麼用呢? this

Func<int,int> f = a=>{return a+1;};
    int b = f(1);

結果b=2spa

2.封裝一個具備兩個參數並返回 TResult 參數指定的類型值的方法。code

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1,T2 arg2)

這個委託有3個類型參數,兩個輸入參數和返回值:
in T1:此委託封裝的方法的第一個參數類型。
in T2:此委託封裝的方法的第二個參數類型。
out TResult:此委託封裝的方法的返回值類型
那麼這個委託怎麼用呢? 對象

Func<int,int,int> f = (a,b)=>{return a+b;}
   int b = f(1,2);

結果b=3blog

Func<int,int,bool> f1 = (a,b)=>{

       if(a==b){

             return true;

       }else{

             return false;

       }

};
bool b = f1(1,2);

結果:b=false繼承

有了這兩個委託後,下面就能夠來研究一下IQueryable< T> 接口的擴展方法了,這些擴展方法基本上就是圍繞着這兩個委託來進行的。

首先咱們來看看Where的擴展方法,這個擴展方被重載了四次,可是因爲在Ling To Entity中,有二個重載方法不被支持,因此這裏就不在對這二個重載函數進行講解了。

wps_clip_image-3231

從圖上能夠看到有四個重載方法,可是對於類型是Expression參數類型的是專門針對Entity Framework的,因此對與沒有Expression參數的方法是從IEnumerable<T>中繼承過來的。而對於Func<TSource,Int32,Boolean>類型參數的方法是不被Entity Framework支持的。

下面咱們主要來看看這個方法:

public static IQueryable<TSource> Where<TSource>(

    this IQueryable<TSource> source,

    Expression<Func<TSource, bool>> predicate

)

類型參數

TSource

source 中的元素的類型。

參數

source

類型: System.Linq.IQueryable<TSource>

要篩選的 IQueryable<T>。

predicate

類型: System.Linq.Expressions.Expression<Func<TSource, Boolean>>

用於測試每一個元素是否知足條件的函數。

返回值

類型: System.Linq.IQueryable<TSource>

一個 IQueryable<T>,包含知足由predicate 指定的條件的輸入序列中的元素。

須要注意的是凡是實現IQueryable<T>的類基本上都是一個集合類,因此這個參數是判斷集合中的每一個元素是否知足條件的,因此這個委託的輸入參數類型是TSource就是集和中的元素類型,若是這個元素知足條件,則返回一個bool值。

Demo:

List<string> list = new List<string>{「aa」,」bb」,」cccc」,」ff」};

   IQueryable<string> query=list.Where<string>(a=>a.Length>3);

當list調用where方法的時候,因爲list中存放的元素類型是string因此where的輸類型參數也是string,而後看一下輸入參數Func<string,bool>,這個委託是用於判斷list集合中每一個元素的表達式,當知足條件的時候會把這個元素放入一個臨時集合中,一直到吧list中全部元素都判斷完畢以後,那麼臨時集合中存放的就是知足條件的元素,而後把這臨時的集合返回出去賦值給IEnumrable<string>

下面咱們來模擬一下這個where方法的原理:

where<string>(Expresssion<Func<TSource, bool>> predicate)

  {

         IQueryable<string> result = new List<string>();

         foreach(string str in this)

        {

            if(predicate(str))

            {

                list.Add(str);

            }

        }

     return result;

}

當把predicate = a=>{return a.Length>3;}傳遞給這個函數的時候,在函數的if語句中就會循環的判斷這個集合中的元素,把知足的元素添加到臨時的list中,最後返回。

下面咱們來看看Select方法:

wps_clip_image-6565

從圖上能夠看出,這個方法也是重載了4次,齊總Expression是針對Entity Framework的,可是參數Func<TSourse,Int32,TResult>是不被支持的。看到這裏的時候,咱們會很是的鬱悶,Where方法和Select方法都有一個Expression參數的方法,可是Expression是什麼,和沒有Expression的方法有什麼區別嗎?其實這是微軟對Entity Framework作的一個優化,Expression是「表達式樹」,經過Expression能夠吧表達式嵌入到SQL語句中造成一個優化的SQL,而沒有Expression的方法,不會生成優化的SQL語句,在網上你們能夠看看Func<TSource,TResult>陷阱的文章。因此呢,這裏咱們推薦使用的是Expression類型的表達式樹。

public static IQueryable<TResult> Select<TSource, TResult>(

    this IQueryable<TSource> source,

    Expression<Func<TSource, TResult>> selector

)

TSource

source 中的元素的類型。

TResult

由 selector 表示的函數返回的值類型。

參數

source

類型: System.Linq.  IQueryable<  TSource> 
一個要投影的值序列。

selector

類型: System.Linq.Expressions.  ExpressionFunc<  TSource, TResult>  > 
要應用於每一個元素的投影函數。

返回值

類型: System.Linq.  IQueryable<  TResult> 
一個 IQueryable<  T> ,其元素爲對source 的每一個元素調用投影函數的結果。

List<Student> list = new List<Student>()

{

      new Student(){SId=1,SName="濟公",SAge=56,SSex="",CId=1},

      new Student(){SId=2,SName="飛龍僧",SAge=25,SSex="",CId=2},

      new Student(){SId=3,SName="劉太真",SAge=34,SSex="",CId=2},

      new Student(){SId=4,SName="玉面仙姑",SAge=78,SSex="",CId=1},

      new Student(){SId=5,SName="東方太悅",SAge=90,SSex="",CId=3},

      new Student(){SId=6,SName="無語老祖",SAge=123,SSex="",CId=3},

      new Student(){SId=7,SName="黃淑女",SAge=23,SSex="",CId=2}

};

IQueryable<string> query = list.Select<Student, string>(student => student.SName);

foreach (string name in query)
 {
     Console.WriteLine(name);
}

在使用select方法的時候,指定了集合中的元素類型和返回值中的元素類型。其中要查詢的集合元素類型爲Student,而返回值的類型是string。所在在lambda中咱們指定返回student.SName類型。

固然了,咱們還能夠指定多個列。代碼以下:

IQueryable<List<string>> query = list.Select<Student, List<string>>(student => { return new List<string> { student.SName, student.SAge + "" }; });

   foreach (List<string> row  in query)

   {

         Console.WriteLine(row[0] + "  " + row[1]);

   }

在這個方法中,咱們指定了返回的類型是List<string>。因此在Lambda中咱們建立了一個List<string>對象,用於保存每一個元素的SName,SAge兩個屬性。這裏須要注意的是在List<student>中的每一個元素的SName,SAge都是一個List<string>。

本章就寫到這裏吧,本章之講解了Where和Select兩個擴展方法,東西很少,可是對於那些還停留在入門的朋友來講,能夠做爲參考文章。那麼在接下來的文章中,老魏還會繼續探討一下這些經常使用的擴展方法,並經過實例來顯示這些方法在Entity Framework中怎麼使用。但願能給你們帶來幫助!順便這裏老魏說一下,發表文章的時間仍是不肯定,由於時間有限,因此只能在閒暇的時間來寫文章了。

相關文章
相關標籤/搜索