九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Entity Framework4.0 (五) EF4的 Query (查詢)功能

Entity Framework4.0 (五) EF4的 Query (查詢)功能


前面一篇介紹了EF4的幾個常概念:Context,SSDL,CSDL,Mapping,Entity,EntitySet,Property,Container,Association,Realationship等。因?yàn)檫@些概念在后面都會用到,所以在讀了概述部分以后,就是該了解這幾個概念的時候了。至于EF4內(nèi)部,如何作狀態(tài)跟蹤,多線程管理,數(shù)據(jù)同步,實(shí)體與實(shí)體集的內(nèi)存模型等這些深入的知識,我想還是到后面再深入學(xué)習(xí)。

對于新知識的引用,我比較贊成“從一個(即:概貌)出發(fā),再脈絡(luò)(即:一些骨架概念和常規(guī)操作),最后細(xì)節(jié)(即:內(nèi)部實(shí)現(xiàn)框架所用到的設(shè)計模式)”這樣一個過程,我覺得這樣不容易迷失于細(xì)節(jié)中。所謂:不識廬山真面目,只緣身在此山中。哈哈。

好了,閑言少敘,書歸正傳。這一篇介紹:EF4的查詢方法:Query。

=====================================================================

首先,我們有兩種方式去查詢:

1. 通過LINQ表達(dá)式:

使用前面EFDemo示例中的代碼段:

LINQ表達(dá)式
 1             using (NorthwindEntities context = new NorthwindEntities())
2 {
3 var products = from product in context.Products
4 join category in context.Categories on product.CategoryID equals category.CategoryID
5 where category.CategoryName == categoryName
6 select new { product.ProductName };
7
8 foreach (var p in products)
9 {
10 this.lboxProduct.Items.Add(p.ProductName);
11 }
12 }


代碼解釋:

第1行:使用using 語句塊去new出來一個容器類NorthwindEntities 的對象context。使用using語句塊的好處是在語句塊結(jié)束的時候context對象會銷毀,其內(nèi)部保持的與數(shù)據(jù)庫的連接也將會釋放。

第3行:使用 var定義一個臨時變量。變量的類型交由編譯器推斷得知(其實(shí)由LINQ表達(dá)式返回的是IEnumerable<Object>的類型)。賦值表達(dá)式右邊的部分就是LINQ內(nèi)容了。這部分和我們最熟悉的T-SQL很像:里面也有select, from ,where ,join,等關(guān)鍵詞。與T-SQL不同的是select的次序在from后面,from的次序一定是在最前面的。這種順序可能會讓人感覺到不自然,不容易接受,畢竟我們的第一印象是Select * from table where 。。。。不要奇怪:其實(shí),當(dāng)我們寫完T-SQL以后,數(shù)據(jù)庫在執(zhí)行T-SQL腳本時的順序是下面這樣(數(shù)字代表執(zhí)行先后的順序由小到大:由1--》8):

  • (8) SELECT (9) TOP
  • (1) FROM
  • (3) JOIN
  • (2) ON
  • (4) WHERE
  • (5) GROUP BY
  • (6) WITH
  • (7) HAVING
  • (1) ORDER BY

上面這種順序和LINQ的順序基本上是一致的。所以大家好容易接受了吧。還有一個原因把from子句寫到前面:當(dāng)我們在寫完from子句以后,visual studio就知道我們要查的是哪個類的實(shí)體了,所以就可以給我們智能提示了:我們打完“.”后,就能提示里面的可用屬性或方法了。如果把from子句放到后面,Visual studio再智能,也不可能幫我們提示,因?yàn)樗⒉荒懿孪氤鑫覀兿胍獙懗龅拇a內(nèi)容是什么。對吧?呵呵。

第4行是作一個連接,和T-SQL一樣的。

第5行是篩選條件,如果where子句,則相當(dāng)于無篩選條件,查詢并返回所有記錄。

第6行   select new { product.ProductName }; 是指生成一個匿名類的對象。這是.NET3.5的新特性,我會在以后專門寫.NET的文章來講這些內(nèi)容的。這里只要知道是生成一個新對象,并把product.ProductName 作為實(shí)參傳進(jìn)去用于初始化對象就好了。如果直接使用 select product,則是選出product的所有屬性。就像T-SQL的select * 一樣。上面是為了順便演示連接(join)的方式,其實(shí)更簡單的方式也可在按方法二(如下:)

方法二:不用連接的LINQ
 1  // 方法二:該方法是指定數(shù)據(jù)源的方式。不須要用 this.lboxProduct.Items.Clear();
2 if (this.lboxCategory.SelectedValue != null)
3 {
4 // 得到類別ID號
5 int categoryID = Convert.ToInt32(this.lboxCategory.SelectedValue.ToString());
6
7 // 這次直接使用CategoryID作篩選條件,不需要使用連接(join),因?yàn)镻roduct中包含有CategoryID。
8 using (NorthwindEntities context = new NorthwindEntities())
9 {
10 var products = from product in context.Products
11 where product.CategoryID == categoryID
12 select new { product.ProductName };
13
14 // 注意:給控制指定數(shù)據(jù)源的時候,對DataSource的賦值語句要在DisplayMember和ValueMember賦值之后,
15 // 否則,DisplayMember和ValueMember的賦值不生效。
16 this.lboxProduct.DisplayMember = "ProductName";
17 this.lboxProduct.DataSource = products;
18 }
19 }


LINQ語言直觀,易懂。推薦使用。

2. 函數(shù)方式。

方法二代碼中查詢語句塊

1                      var products = from product in context.Products
2 where product.CategoryID == categoryID
3 select new { product.ProductName };

 

,也可以換成下面的:

1                     var products = context.Products.
2 Where<Product>(p => p.CategoryID == categoryID).
3 OrderBy(d => d.ProductName).
4 Select(s => new { s.ProductName});

現(xiàn)在的Where(),OrderBy(),Select()都成了方法名,而不是關(guān)鍵字了,是由靜態(tài)類Queryable里面的靜態(tài)方法。而且這些方法全是擴(kuò)展方法(關(guān)于擴(kuò)展方法也是.NET3.5的新特性)。使用擴(kuò)展方法,可以給一個把一個靜態(tài)方法添加到某一個已有的類中。靜態(tài)類Queryable就是把Where(),OrderBy(),Select()等這些靜態(tài)方法擴(kuò)展給了IQueryable<T>和IQueryable<T>的子類們。代碼中由容器類NorthwindEntities的對象得到的context.Products 就是ObjectSet<TEntity>,而 ObjectSet<TEntity>,實(shí)現(xiàn)了IQueryable<T>接口。所以可以調(diào)用這些靜態(tài)方法。方法參數(shù)是Lambda表達(dá)式。Lambda表達(dá)式就是一個簡化的匿名委托的實(shí)現(xiàn)函數(shù):

p => p.CategoryID == categoryID 代表的意思是:

  • 1. 一個函數(shù)的參數(shù)是:p(類型不必指定,由編譯器推斷得到) 
  • 2. 函數(shù)體是: p.CategoryID == categoryID
  • 3. 該方法沒有名字
  • 4. 返回值是bool型

雖然該方法沒有名字,但可在被定義的同時,作為實(shí)參,傳給一個和該匿名方法的簽名一樣的委托作形參的函數(shù),如 Expression<Func<TSource, bool>> ,where函數(shù)原型如下:

Where
1 public static IQueryable<TSource> Where<TSource>(
2 this IQueryable<TSource> source,
3 Expression<Func<TSource, bool>> predicate
4 )

上面代碼:this IQueryable<T> source  參數(shù)表示:把方法Where<T>()擴(kuò)展給了IQueryable<T> 類。this后的類型代表擴(kuò)展的目標(biāo)類型(就是要把該方法擴(kuò)展給那個類,也就是該類的實(shí)例成員就可以像調(diào)用自己類內(nèi)定義的方法一樣調(diào)用該方法,并且在調(diào)用where()的時候,參數(shù)列表就變成了where(Expression<Func<TSource,bool>> predicate),就是要不包含this所修飾的參數(shù)。因?yàn)閠his修飾后的參數(shù)是指擴(kuò)展目標(biāo)類型。this用于表明該擴(kuò)展類型的對象是放到該函數(shù)名前面使用的,并不是當(dāng)作函數(shù)參數(shù)傳到函數(shù)內(nèi)部。)

Expression 類的定義是:public sealed class Expression<TDelegate> : LambdaExpression

Func<>是FCL(Framework Class Library)中定義的委托。在自己的程序中可以直接使用。在構(gòu)造Expression類的時候,用該Func委托作形參。而實(shí)參就是這個Lambda表達(dá)式:
p => p.CategoryID == categoryID 。

其實(shí),在使用的時候,直接以函數(shù)的形式去使用,按Lambda表達(dá)的方式去傳值就行了。很簡單,很好用的,不必考慮這些復(fù)雜的委托的實(shí)例與調(diào)用是如何封裝的。函數(shù)名字也和我們之前使用T-SQL的關(guān)鍵字一樣。

注意:

1. 然我們寫代碼的時候,是調(diào)用完一個函數(shù)后再調(diào)用另一個函數(shù)。但是在代碼執(zhí)行的時候,是把這些函數(shù)組合成一個sql語句后,一并執(zhí)行的。

2. 延遲執(zhí)行:下面這段代碼中,var categories 的賦值語句執(zhí)行后,var其實(shí)并沒立即從數(shù)據(jù)庫中查詢數(shù)據(jù),而只是保存一條查詢命令。真正執(zhí)行查詢的時刻是把categories作為集合遍歷時,或作為數(shù)據(jù)源時。(如果你想驗(yàn)證的話,不要試圖設(shè)置斷點(diǎn),去查看categories變量的值,因?yàn)槟惝?dāng)你用斷點(diǎn)去調(diào)試時,visual studio會告訴你“如果你要查看它的查詢結(jié)果,將進(jìn)行數(shù)據(jù)查詢”所以,你是無法通過斷點(diǎn)來查categories變量的值。但是你可設(shè)置斷點(diǎn),單步執(zhí)行,然后觀察數(shù)據(jù)庫偵測工具Data profile viewer的結(jié)果。由于我家用上電腦沒有裝這個工具,所以無法截圖了。但是大家只要心里清楚執(zhí)行是什么時候就ok了。)

延遲執(zhí)行示例代碼
 1   using (NorthwindEntities context = new NorthwindEntities())
2 {
3 var categories = from category in context.Categories
4 select new { category.CategoryID,category.CategoryName };
5
6 foreach (var c in categories)
7 {
8 this.lboxCategory.Items.Add(c.CategoryName);
9 }
10 }

這就是所謂的延遲執(zhí)行。如果你想要它立即執(zhí)行查詢可以用下面的方法:

立即執(zhí)行的示例代碼
 1   using (NorthwindEntities context = new NorthwindEntities())
2 {
3 var categories = (from category in context.Categories
4 select new { category.CategoryID,category.CategoryName }).ToList();
5
6 foreach (var c in categories)
7 {
8 this.lboxCategory.Items.Add(c.CategoryName);
9 }
10 }

上面代碼第4行使用了ToList()方法,使其立即執(zhí)行。同樣這樣的方法還有:ToDictionary(),First(),ToArray(),Count(),ToLookUp(),Average()等,只要你輸入“.”以后查看下智能提示就知道有哪些函數(shù)可用了。而這些函數(shù)的用法通過函數(shù)名字基本上也就非常清楚了。呵呵,如果不確定的話,直接可以到谷歌搜下,很簡單的方法。

在LINQ結(jié)合EF4的使用就是:LINQ to Entity了,除此以外還有LING to SQL,LINQ to XML, LINQ to Dataset等,以后專門在LINQ的文章中討論,在這里討論太多的話,就跑題了,呵呵。

休息咯??!晚安,各位。。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
EntityFamework 4.0 中的并發(fā)處理(一) - PetterLiu - 博客園
微型 ORM-FluentData 溫故知新系列
XML數(shù)據(jù)類型的查詢方法
Linq To Sql進(jìn)階系列(四)User Define Function篇
在MongoDB中實(shí)現(xiàn)聚合函數(shù)
EF Code First 一對多、多對多關(guān)聯(lián),如何加載子集合?
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服