LINQ查詢探討:一個(gè)主從報(bào)表和數(shù)據(jù)統(tǒng)計(jì)
在LINQ 查詢中,始終會(huì)用到對(duì)象。可以使用相同的基本編碼模式來查詢和轉(zhuǎn)換 XML 文檔、SQL 數(shù)據(jù)庫、ADO.NET 數(shù)據(jù)集、.NET 集合中的數(shù)據(jù)以及對(duì)其LINQ 提供程序可用的任何其他格式的數(shù)據(jù)。
以前,我們要在某個(gè)報(bào)表中顯示統(tǒng)計(jì)信息一般有兩種方法:1通過一個(gè)SQL查詢——我們可以向數(shù)據(jù)庫發(fā)出一個(gè)額外的查詢來為某個(gè)特定的類別計(jì)算統(tǒng)計(jì)信息。SQL包含一系列的聚合函數(shù),并由GROUP BY子句指定應(yīng)該根據(jù)什么數(shù)據(jù)來進(jìn)行統(tǒng)計(jì)。2在表示層中統(tǒng)計(jì)已經(jīng)獲取的信息。
然而這兩個(gè)方法都有他們的缺點(diǎn):
第一種方法很明顯,他增加了一次到數(shù)據(jù)庫的往返,因?yàn)樵讷@取報(bào)表信息的時(shí)候我們已經(jīng)對(duì)數(shù)據(jù)庫進(jìn)行了一次訪問,而我們要獲得的統(tǒng)計(jì)信息可以從報(bào)表中獲取。而且無法獲取更加復(fù)雜的業(yè)務(wù)統(tǒng)計(jì)。
第二種方法則沒有很好的讓層次劃分出來,我們更加希望表示層中僅僅使用方法而不要去設(shè)計(jì)這些方法。(尤其是一些業(yè)務(wù)規(guī)則,比如NBA中有“球員效率”這項(xiàng)數(shù)據(jù),但如果不是很熟悉這項(xiàng)業(yè)務(wù)的程序員是不知道這個(gè)效率是如何計(jì)算的。)
既然我們使用了分層架構(gòu),就應(yīng)該把這些職能分開,表示層的設(shè)計(jì)者只需要設(shè)計(jì)UI,了解方法的名稱就可以了。具體的業(yè)務(wù)計(jì)算應(yīng)該留下來給業(yè)務(wù)邏輯層的設(shè)計(jì)者去設(shè)計(jì)。
有了LINQ查詢我們就可以把這些東西都放到業(yè)務(wù)層去了,因?yàn)閿?shù)據(jù)操作已經(jīng)對(duì)象化,在邏輯層中就可以方便地統(tǒng)計(jì)數(shù)據(jù)并且直接在表示層調(diào)用這樣的方法。
按部就班的做
1我們需要一個(gè)下來列表來選擇門類,所以我們需要一個(gè)門類列表,在Productbll中添加一個(gè)新的方法GetCategory代碼如下:
- [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
- public IQueryable GetCategory()
- {
- var category = from p in db.Categories
- select p;
- return category;
- }
2.代碼很簡(jiǎn)單我就不解釋了,由于我們的重點(diǎn)不是這個(gè)門類選擇列表,所以我直接選擇了全部字段,其實(shí)只要ID和Name兩個(gè)字段就可以了。新建一個(gè)WEB窗體,添加一個(gè)下拉列表,在自動(dòng)回送上打勾,選擇新建數(shù)據(jù)源。
3.LINQ查詢下數(shù)據(jù)源選擇對(duì)象數(shù)據(jù)源,選擇Productbll,方法選擇GetCategory,點(diǎn)擊完成。字段顯示填寫CategoryName,字段值填寫CategoryID。
4.然后就是顯示統(tǒng)計(jì)和從報(bào)表的方法,在GetCategory方法下添加一個(gè)新方法GetProductByCategoryID,代碼如下:
- [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
- public IQueryable GetProductByCategoryID(int categoryID,out decimal? total)
- {
- total = 0;
- var product = from p in db.Products
- where p.CategoryID == categoryID
- select p;
- foreach (Product p in product)
- total += p.UnitPrice;
- return product;
- }
5.簡(jiǎn)單的代碼解釋:
1)這是一個(gè)包含2個(gè)輸出的方法,方法本身是可以作為數(shù)據(jù)源的IQueryable類型,另外還會(huì)輸出一個(gè)十進(jìn)制類型數(shù),也就是總價(jià)
2)獲取CategoryID與輸入?yún)?shù)categoryID相匹配的記錄
3)遍歷這些記錄,獲取他們的價(jià)格之和
4)返回這些記錄與總價(jià)
6.在頁面中添加一個(gè)GridView與一個(gè)Lable控件,雙擊下拉列表,進(jìn)入事件,加入如下代碼:
- decimal? sum = 0;
- GridView1.DataSource=product.GetProductByCategoryID(Convert.ToInt16(DropDownList1.SelectedValue),out sum);
- GridView1.DataBind();
- Label1.Text = "總價(jià):"+Convert.ToString(sum);
7.運(yùn)行該頁面,任意選擇一個(gè)門類,觀察總價(jià)和這些記錄。
小結(jié):
這章的內(nèi)容并不多,需要注意的是我們使用了返回多個(gè)結(jié)果的方法,方法本身是IQueryable類型,另外還會(huì)輸出一個(gè)十進(jìn)制類型數(shù),也就是總價(jià)。我們?cè)谶壿媽又欣肔INQ查詢結(jié)果,并且進(jìn)行遍歷,獲得總價(jià)。在表示層中我們僅僅調(diào)用了方法,而且對(duì)數(shù)據(jù)庫僅有一次操作。
比起直接用SQL獲取總價(jià)來說,我們的方法少了一次數(shù)據(jù)庫的往返。比起在表示層寫方法,我們的方法的層次更加分明。在沒有使用這樣的結(jié)構(gòu)以前,也可以在邏輯層這么做,只不過還需要手動(dòng)的把數(shù)據(jù)轉(zhuǎn)換成可以遍歷的對(duì)象,而現(xiàn)在一切都方便了。可以直接對(duì)Product表中的記錄使用for each.除此之外我們不需要做更多的工作。
本貼來自天極網(wǎng)群樂社區(qū)
【編輯推薦】