天天看點

[置頂] SPL講解(7)--Query進階篇

SmartPersistenceLayer 2.0 之Query進階查詢篇

總述

在看了前面的功能後,大家都會考慮到多表之間的查詢怎麼辦.在這裡,我想先講一下查詢在應用系統中的複雜性/重要性/可行性.

重要性:查詢統計是系統維護的一個目标之一,是系統的一個必不可少的部分,是以,在絕大部分的系統中,都會有查詢統計。

複雜性:查詢是在系統開發中一個最複雜的部分,誰都無法預料查詢統計的複雜性,哪怕是在一個小型系統中,是以,在SPL中也是無法實作這麼多的查詢統計,為了相容,SPL也努力實作了它所能做的,就是”聯合查詢”功能,将通過Query類來完成.

可行性:要能快速,有效的應付複雜多變的查詢與統計,在我看來,用視圖進行處理是一個最有效的方式.一是視圖的高速:資料庫的視圖查詢要比執行SQL來的快多,因為資料庫會為視圖進行緩存.二是開發快速性:寫SQL語句需要很多時間,而且查詢彙總的語句都是相當複雜的,是以也容易出錯,而視圖會把問題變的非常簡單,開發速度大大提高.三是維護性:由于查詢的複雜性,變動頻繁将是最明顯的特征,是以SQL語句的應變能力沒有視圖來得好.

       是以,我的建議是對于一些查詢與統計,我們應盡可能的采用視圖來做.簡單的查詢當然可以使用SQL.現在來介紹SPL中的Query聯合查詢.

聯合查詢

例子:A表的ID與B表的AID有關聯,我們要關聯A/B表,選擇A表的NAME和B表的COMPANY值.

Query q1=new Query(typeof(A));           //建一個A表的Query

q1. AddAttribute(A.NAME);                    //添加一個要選擇的字段

Condition c=q1. GetQueryCondition();         //A表産生一個查詢

c.AddEqualTo(“Name”,”tintown”);              //給A添加條件,請參考Condition

q1.OrderBy(“Name”);                     //添加一個排序,請參考RetrieveCriteria

Query q2=new Query(typeof(B));              //建一個B表的Query

q2.AddAttribute(B.COMPANY,”公司名”);      //添加另一個選擇的字段,以别名輸出

q1. AddJoinQuery(A.ID,q2,B.AID);            //把q1與q2關聯起來

DataTable dt=q1. Execute();                 //執行查詢

步驟分析:

1. Query的建立與Criteira差不多一樣的,要指定一個實體類型typeof(A)

2. 由于是多表查詢,是以要求設定選擇哪些字段,目前SPL中有三種方式:

1.      AddAttribute(字段名):這是直接以字段名為輸出名

2.      AddAttribute(字段名,别名):這是可以把字段名以别名的方式輸出

3.      AddAttribute(AttributeType.All):這是指以*号的方式全部顯示

   3. 使用Execute()執行後傳回DataTable類型,可以直接綁定用。

       在使用這種輸出字段時,要注意不能重名輸出,尤其是在使用了*号後,因為會正在一些不可預測的字段重名,是以,建議盡可能使用别名

通過以上的方式就可以實作大多數表之間的聯合查詢.以上有個局限性:表寫表之間的關系都是inner join的.也就是無法實作左連接配接效果,對于這種查詢,我還是建議使用視圖.

     其他的Condition與OrderBy都與RetrieveCriteria類似,不再贅述。

統計查詢

對于彙總查詢本身也是非常複雜的,SPL也隻能實作簡單的彙總,對于複雜性的彙總還是建議使用視圖或是SQL進行.

Query q1=new Query(typeof(A));

q1.AddAttribute(A.NAME):                 //顯示NAME

q1.SelectMax(A.PRICE,”MAXPRICE”);             //統計最高價格,别名MAXPRICE

q1.SelectSum(A.PRICE,”ALLPRICE”);              //統計價格總和,别名ALLPRICE

q1.SelectAvg(A.PRICE,”AVGPRICE”);             //統計平均價格,别名AVGPRICE

q1.SelectCount(A.NAME,”COUNT”);               //統計條數,别名COUNT

q1.GroupBy(A.NAME);                           //接NAME進行分組

q1. Execute();                                 //執行

使用SelectMax,SelectSum,SelectAvg,SelectCount進行簡單的彙總,上面的例子是顯示多彙總值的情況,是以是采用Execute()方法.

SPL還提供了單傳回的方式:

Query q=newQuery(typeof(A);

       q.SelectCount(A.ID);

       intre=q. ExecuteScalar();

       這可以傳回條數,其實在SPL中就是擷取第一條記錄的第一列值。

SQL語句執行

為了擴充相容性,還是要提供最基本的SQL語句執行接口,對于一些複雜的語句,可以使用SQL語句的執行來解決,實作的方式也是非常簡單:

string sqlString=”select name from A whereprice>1000”;

Query. ProcessSql(sqlString,”dbName”);

這裡的dbName 是指語句針對哪個資料源進行操作,當然要注意的,通過SQL執行傳回的字段名,是資料庫的實際的字段名了,而不是實體的屬性名了。

DISTINCT功能

     在SPL中可以使用IsDistinct屬性來使用DISTINCT功能,這将最終生成”Select distinct…”的語句。

存儲過程

       SPL中也同樣支援存儲過程,我們也可以通過Query的靜态類完成:

       IDataParameterpara=Query.GetParameter("northwind"); //建立一個參數

     para.ParameterName="@name1";  //定義參數名

     para.Value="f";              //定義參數值