使用OQL+SQLMAP解決ORM多表複雜的查詢問題
一般情況下,使用ORM框架來完成單個實體的查詢是很方便的,但如果有複雜的查詢條件,普通的ORM元件比較困難,PDF.NET資料開發框架的ORM實體類查詢語言--OQL,使得構造複雜的查詢條件成為可能,參加我的其它相關文章。
很多ORM框架都只能處理單個實體的查詢,但如果要連表查詢就比較困難了,主要問題是連表查詢的結果無法投射到一個實體類中,這時候只有動態建立一個類來處理,比如LINQ的Select功能。在PDF.NET資料開發框架中,多表連線查詢推薦使用SQL-MAP功能(參加我的相關文章),將複雜的SQL語句寫到SQL-MAP配置檔案中,然後使用程式碼生成器生成SqlMapDal類檔案,供業務層使用。
今天有一個同事需要在實體類的條件中增加一個複雜的In查詢,由於In的條件有4萬條,採用SQL的In查詢效率極其低下,但是採用Inner Join查詢能夠提升5倍的查詢效率,而框架的ORM又不支援多表連線查詢,單獨使用SQL-MAP功能,要大量修改原有程式碼,原有程式碼是一個長達4000行的方法,那個方法最有大量的迴圈和分支,用於構造實體類的查詢條件物件(OQLCompare物件),最終構造了一個複雜的OQL查詢條件:
OQL oql=GetOQLbyBussiness();//這個方法有4000行程式碼; string sql=oql.ToString();//大致是 select * from table1 where condition1 sql=GetInnerJoinSql(sql,"另外一個表的查詢語句"); //執行這個方法將得到大致的查詢語句 //select * from table1 t1 inner join table2 t2 where t1.CID=t2.Cid and condition1
本來使用 EntityQuery<EntityModelClass>.Query(oql) 即可獲得 List<EntityModelClass>,但現在為了新增另外一個表的查詢,將oql轉換成了sql語句,怎麼能夠再次生成實體類呢?
現在,我們可以使用SQL-MAP來幫助了。
開啟原來的SqlMapDal檔案,為了不讓程式碼生成器覆蓋自動生成的檔案,我們新建一個分部檔案,手寫如下程式碼:
using System; using System.Data; using System.Collections.Generic; using PWMIS.DataMap.SqlMap; using PWMIS.DataMap.Entity; using PWMIS.Common; using XXModel; namespace XXDAL.SqlMapDAL { public partial class CustomerManage : DBMapper { public List<CustomerClassification> GetCustomerList(string sql, Dictionary<string, object> ps) { IDataParameter[] paras = new IDataParameter[ps.Count]; int i = 0; foreach (string key in ps.Keys) paras[i++] = CurrentDataBase.GetParameter(key, ps[key]); return EntityQuery<CustomerClassification>.QueryList(CurrentDataBase.ExecuteReader(CurrentDataBase.ConnectionString, System.Data.CommandType.Text, sql, paras)); } } }
然後,在業務層中,如下呼叫即可:
XXDAL.SqlMapDAL.CustomerManage manage=new XXDAL.SqlMapDAL.CustomerManage();
List<CustomerClassification> customerClass=manage.GetCustomerList(sql,oql.DataParameters);
這樣就獲得了我們的最終結果。
請注意,我們把oql的引數物件DataParameters 傳遞給了DAL方法,用於構造引數化查詢。
總結:
結合使用PDF.NET框架的OQL+SQLMAP,可以在不放棄實體類的便利情況下,進行復雜的多表查詢!