使用PDF.NET資料開發框架的實體操作語言OQL構造複雜查詢條件
PDF.NET資料開發框架(Pwmis Data develop Framework,http://www.pwmis.com/sqlmap) 是一套借鑑iBatis、Hibernate、Linq等資料訪問框架而來的輕量級資料開發框架,主要特點是具有iBatis特點的SQL-MAP功能和框架獨特的實體物件查詢語言--OQL,下面我們使用OQL來構造一個複雜的實體查詢。
首先定義兩個實體類:使用者類和訂單類,可以使用框架提供的實體類生成器生成,下面是詳細程式碼:
/* 本類由PWMIS 實體類生成工具(Ver 4.1)自動生成 http://www.pwmis.com/sqlmap 使用前請先在專案工程中引用 PWMIS.Core.dll 2010/12/8 15:01:22 */ using System; using PWMIS.Common; using PWMIS.DataMap.Entity; namespace LocalDB { /// <summary> /// 使用者表 /// </summary> [Serializable()] public partial class Table_User : EntityBase { public Table_User() { TableName = "Table_User"; EntityMap=EntityMapType.SqlMap; //IdentityName = "標識欄位名"; IdentityName="UID"; //PrimaryKeys.Add("主鍵欄位名"); PrimaryKeys.Add("UID"); PropertyNames = new string[] { "UID","Name","Sex","Height","Birthday" }; PropertyValues = new object[PropertyNames.Length]; } /// <summary> /// 使用者標識 /// </summary> public System.Int32 UID { get{return getProperty<System.Int32>("UID");} set{setProperty("UID",value );} } /// <summary> /// 姓名 /// </summary> public System.String Name { get{return getProperty<System.String>("Name");} set{setProperty("Name",value ,50);} } /// <summary> /// 性別 /// </summary> public System.Boolean Sex { get{return getProperty<System.Boolean>("Sex");} set{setProperty("Sex",value );} } /// <summary> /// 身高 /// </summary> public System.Double Height { get{return getProperty<System.Double>("Height");} set{setProperty("Height",value );} } /// <summary> /// 出生日期 /// </summary> public System.DateTime Birthday { get{return getProperty<System.DateTime>("Birthday");} set{setProperty("Birthday",value );} } } /// <summary> /// 訂單表 /// </summary> [Serializable()] public partial class Table_Order : EntityBase { public Table_Order() { TableName = "Table_Order"; EntityMap = EntityMapType.SqlMap; //IdentityName = "標識欄位名"; IdentityName = "OID"; //PrimaryKeys.Add("主鍵欄位名"); PrimaryKeys.Add("OID"); PropertyNames = new string[] { "OID", "UID", "ProductName", "BuyCount", "OrderDate" }; PropertyValues = new object[PropertyNames.Length]; } /// <summary> /// 訂單編號 /// </summary> public System.Int32 OID { get { return getProperty<System.Int32>("OID"); } set { setProperty("OID", value); } } /// <summary> /// 使用者號 /// </summary> public System.Int32 UID { get { return getProperty<System.Int32>("UID"); } set { setProperty("UID", value); } } /// <summary> /// 產品名字 /// </summary> public System.String Name { get { return getProperty<System.String>("ProductName"); } set { setProperty("ProductName", value, 50); } } /// <summary> /// 購買數量 /// </summary> public System.Int32 Count { get { return getProperty<System.Int32>("BuyCount"); } set { setProperty("BuyCount", value); } } /// <summary> /// 購買日期 /// </summary> public System.DateTime OrderDate { get { return getProperty<System.DateTime>("OrderDate"); } set { setProperty("OrderDate", value); } } } }
然後,我們來構造兩個複雜的查詢條件,直接上程式碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PWMIS.DataMap.Entity; namespace TestSqlMapEntity { class Program { static void Main(string[] args) { LocalDB.Table_User user = new LocalDB.Table_User(); List<OQLCompare> OrCmp1 = new List<OQLCompare>(); OQLCompare cmp = new OQLCompare(user); OrCmp1.Add(cmp.Comparer(user.UID, "=", 1)); OrCmp1.Add(cmp.Comparer(user.UID, "=", 2)); OrCmp1.Add(cmp.Comparer(user.UID, "=", 3)); List<OQLCompare> OrCmp2 = new List<OQLCompare>(); OrCmp2.Add(cmp.Comparer(user.Name, "=", "aaa")); OrCmp2.Add(cmp.Comparer(user.Name, "=", "bbb")); OQLCompare result = new OQLCompare( cmp.Comparer(OrCmp1, OQLCompare.CompareLogic.OR), OQLCompare.CompareLogic.AND, cmp.Comparer(OrCmp2, OQLCompare.CompareLogic.OR)); OQL oql = OQL.From(user).Select().Where(result).END; Console.WriteLine("OQL To SQL is:rn" + oql.ToString()); /* * * OQL To SQL is: SELECT UID,Name,Sex,Height,Birthday FROM Table_User Where ( ( UID = @CP1 Or UID = @CP2 Or UID = @CP3 ) AND ( Name = @CP4 Or Na me = @CP5 ) ) */ oql.ReSet(); LocalDB.Table_Order order = new LocalDB.Table_Order(); OQL q_order = OQL.From(order).Select(order.UID ).Where( new OQLCompare(order).Comparer(order.OrderDate, ">=", DateTime.Now.AddDays(-10)) ).END ; oql.Select().Where(oql.Condition.AND(user.Sex ,"=",true).IN(user.UID, q_order)); Console.WriteLine("OQL To SQL is:rn" + oql.ToString()); /* * OQL To SQL is: SELECT UID,Name,Sex,Height,Birthday FROM Table_User Where Sex = @Sex0 AND UID IN ( SELECT UID FROM Table_Order Where OrderDate >= @CP1 ) */ Console.Read(); } } }
程式中有兩段程式碼,第一段程式碼是為了構造一個複雜的Where條件:
Where ( ( UID = @CP1 Or UID = @CP2 Or UID = @CP3 ) AND ( Name = @CP4 Or Name = @CP5 ) )
意思是查詢符合條件的多個UID並且查詢符合條件的多個使用者姓名,輸出的完整SQL語句如下:
SELECT UID,Name,Sex,Height,Birthday FROM Table_User Where ( ( UID = @CP1 Or UID = @CP2 Or UID = @CP3 ) AND ( Name = @CP4 Or Name = @CP5 ) )
第二段程式碼是為了以UID為外來鍵,從訂單表中查詢哪些使用者在10日內提交了訂單的使用者資訊,程式聲明瞭兩個OQL物件:
OQL oql;//使用者相關的OQL物件;
OQL q_order //訂單相關的OQL物件;
關鍵點在於q_order 物件作為oql物件的 IN 查詢的引數,實現了SQL的IN子查詢:
oql.Select().Where(oql.Condition.AND(user.Sex ,"=",true).IN(user.UID, q_order));
該條查詢輸出的完整SQL語句如下:
SELECT UID,Name,Sex,Height,Birthday
FROM Table_User
Where Sex = @Sex0 AND UID IN (
SELECT UID
FROM Table_Order
Where OrderDate >= @CP1
)
OK,到此為止,我們可以使用我們的OQL查詢出真正的實體集合了:
List<LocalDB.Table_User> result=EntityQuery<LocalDB.Table_User>.Query(oql);
一行程式碼搞定,是不是很簡單?
PDF.NET的宗旨就是為了最大化精簡你的資料開發,有興趣請看我的部落格其它文章或者到官網:http://www.pwmis.com/sqlmap