国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

SQL查詢語句對象化的實現(C#)

2019-11-18 17:03:56
字體:
來源:轉載
供稿:網友

在開發數據庫應用的過程難免會編寫大量的SQL語句,其中大部份是查詢語句;為不同情況編寫查詢語句是一件很煩瑣的事件。用過hibernate或Nhibernate會了解到把SQL查詢語句對象化后使用起非常方便和快捷;也大大減少在編寫查詢SQL語句所帶來的錯誤等問題。

       前段時間在編寫一個數據處理類的時候同樣遇到這個問題,經過一段時間思考和設計現實現了SQL查詢語句對象化的功能;在這里我把自己小小的成果共享一下。

在講解前先看幾個例子(數據是SQLServer的Northwind)注意:例子中所涉及的除查詢對象化外還包含整個數據處理類的使用,那部分還在設計和完善當中。

 

       1)以上語句是查詢訂單ID為10264的訂單信息

       using(Hfsoft.Data.IDatasession session = HFSoft.Data.DataSessionFactory.OpenSession())

     {

         session.Open();

         HFSoft.Data.QueryCmd query = new QueryCmd("Orders");

         query.ExPReesion.Add(new HFSoft.Data.EqExpression("OrderID",10264));

          System.Data.DataSet myDS = session.ExecuteDataSet(query.BuilderCmd(session));

     }

     對象生成的SQL語句:

SELECT * FROM Orders  where  1=1  And (OrderID = @OrderID0)

 

     2)以上語句是查詢訂單ID大于10264并且小于10600的訂單信息

       using(HFSoft.Data.IDataSession session = HFSoft.Data.DataSessionFactory.OpenSession())

     {

         session.Open();

         HFSoft.Data.QueryCmd query = new QueryCmd("Orders");

         query.Expreesion.Add(  new HFSoft.Data.LeExpression("OrderID",10264),

                                 new HFSoft.Data.RtExpression("OrderID",10600));

         System.Data.DataSet myDS = session.ExecuteDataSet(query.BuilderCmd(session));

     }

     對象生成的SQL語句:

SELECT * FROM Orders  where  1=1  And (OrderID > @OrderID0) And (OrderID < @OrderID1)

 

4)以上語句是查詢訂單ID大于10264并且小于10600或編號是10601,10602,10605的訂單信息

using(HFSoft.Data.IDataSession session = HFSoft.Data.DataSessionFactory.OpenSession())

{

         session.Open();

         HFSoft.Data.QueryCmd query = new QueryCmd("Orders");

         query.Expreesion.Add(  new HFSoft.Data.LeExpression("OrderID",10264),

                       new HFSoft.Data.RtExpression("OrderID",10600));

         query.Expreesion.Add(HFSoft.Data.UintType.Or,new HFSoft.Data.InExpression("OrderID",new int[]{10601,10602,10605}));

         System.Data.DataSet myDS = session.ExecuteDataSet(query.BuilderCmd(session));       }

對象生成的SQL語句:

SELECT * FROM Orders  where  1=1  And (OrderID > @OrderID0) And (OrderID < @OrderID1) Or (OrderID in (@OrderID20,@OrderID21,@OrderID22))

 

從上面的例子我們可以看到對不同的條件進行數據查詢只是一件很簡單的事情,你并不用為不同的查詢情況寫相應SQL語句。

接下來講術這個查詢對象實現,對象的最終就是把不同字符串并起來生成相應的SQL語句;SQL語句查詢語句主要分為以下幾大部份:獲取的字段,表名稱,條件,排序,分組;了解SELECT語句的對查詢語句的組成部分比較了解。

其中比較難的就是條件部分處理,因為條件的組合是情況是比較多;所以設計起來相對比較復雜。在設計的過程中把條件單獨抽取出來,并生成接口對條件的表達式進行描述:

/// <summary>

     /// 表達式描述接口

     /// 用于SQL語句條件表達式的描述

     /// </summary>

     public interface IExpression

     {

         /// <summary>

         /// 獲取表達式

         /// </summary>

         /// <param name="driver">數據處理設備提供者</param>

         /// <returns>string</returns>

         string GetFilter(HFSoft.Data.IDriverType driver);

         /// <summary>

         /// 獲取表達式相關的參數

         /// </summary>

         /// <param name="driver">數據處理設備提供者</param>

         /// <returns>System.Data.IDataParameter[]</returns>

         System.Data.IDataParameter[] GetDataParams(HFSoft.Data.IDriverType driver);

         /// <summary>

         /// 序列標識

         /// 本屬性用于內部處理

         /// </summary>

         string Sequence

         {

              get;

              set;

         }

         /// <summary>

         /// 添加表達式

         /// </summary>

         /// <param name="unittype">合并類型(or|and)</param>

         /// <param name="expressions">表達式對象</param>

         void Add(UintType unittype,params IExpression[] expressions );

         /// <summary>

         /// 添加表達式

         /// </summary>

         /// <param name="expressions">表達式對象</param>

         void Add(params IExpression[] expressions );

        

     }

 

在接口描述中有很多地方離不開HFSoft.Data.IDriverType它是用于描述數據庫類型。根據HFSoft.Data.IDriverType    對應生成SqlServer,MySQL,Oracle等數據庫的條件表達式。

為什么IExpression具有Add方法,并且添加的對象也是IExpression;因為條件自己可以包含多個子表達式,只有這樣才能夠靈活組合成復雜的條件表達式。

 接下來看下基于這個接口的實現
/// <summary>

     /// 表達式基礎類

     /// </summary>

     [Serializable]

     public  class Expression:IExpression

     {

         private string mName;

         /// <summary>

         /// 獲取或設置相關的字段名

         /// </summary>

         public string Name

         {

              get

              {

                   return mName;

              }

              set

              {

                   mName = value;

              }

         }

         private object mValue;

         /// <summary>

         /// 獲取或設置相關的字段值

         /// </summary>

         public object Value

         {

              get

              {

                   return mValue;

              }

              set

              {

                   mValue = value;

              }

         }

         private string mSequence = "";

         /// <summary>

         /// 獲取或設置相關標識

         /// 本屬性用于內部處理

         /// </summary>

         public  string Sequence

         {

              get

              {

                   return mSequence;

              }

              set

              {

                   mSequence = value;

              }

         }

         #region IExpression 成員

         /// <summary>

         /// 獲取表達式

         /// </summary>

         /// <param name="driver">數據處理設備提供者</param>

         /// <returns>string</returns>

         public virtual string GetFilter(HFSoft.Data.IDriverType driver)

         {

              return " 1=1 " + GetSubString(driver);

         }

         /// <summary>

         /// 獲取表達式相關的參數

         /// </summary>

         /// <param name="driver">數據處理設備提供者</param>

         /// <returns>System.Data.IDataParameter[]</returns>

         public virtual System.Data.IDataParameter[] GetDataParams(HFSoft.Data.IDriverType driver)

         {

              return GetSubParams(driver);

         }

        

         #endregion

         private  System.Collections.ArrayList _Expressions = new System.Collections.ArrayList();

         private  System.Collections.ArrayList _Units = new System.Collections.ArrayList();

         /// <summary>

         /// 添加相關表達式

         /// </summary>

         /// <param name="expressions">表達式對象</param>

         public  void Add(params IExpression[] expressions )

         {

              Add(UintType.And,expressions);

         }

         /// <summary>

         /// 添加相關表達式

         /// </summary>

         /// <param name="unittype">表達式合并類型</param>

         /// <param name="expressions">表達式對象</param>

         public  void Add(UintType unittype,params IExpression[] expressions )

         {

              if(expressions != null)

                   foreach(IExpression exp in expressions)

                   {

                       if(exp != null)

                       {

                            _Units.Add(unittype.ToString());

                            exp.Sequence = this.Sequence +_Expressions.Count;

                            _Expressions.Add(exp);

                       }

                   }

         }

         /// <summary>

         /// 獲取內部表達式

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>string</returns>

         protected string GetSubString(HFSoft.Data.IDriverType driver)

         {

              if(_Units.Count == 0)

                   return "";

              System.Text.StringBuilder sb = new System.Text.StringBuilder();

              for(int i =0;i< this._Units.Count;i++)

              {

                   sb.Append(" " +this._Units[i] +" ("+ ((IExpression)_Expressions[i]).GetFilter(driver)+")");

              }

              return sb.ToString();

         }

         /// <summary>

         /// 獲以內部表達式的參數值

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>System.Data.IDataParameter[]</returns>

         protected System.Data.IDataParameter[] GetSubParams(HFSoft.Data.IDriverType driver)

         {

              if(_Expressions.Count ==0)

                   return null;

              if(_Expressions.Count ==1)

              {

                   return ((IExpression)_Expressions[0]).GetDataParams(driver);

              }

              System.Collections.ArrayList lst = new System.Collections.ArrayList();

              foreach(IExpression exp in this._Expressions)

              {

                   System.Data.IDataParameter[] ps = exp.GetDataParams(driver);

                   if(ps !=null && ps.Length >0)

                   {

                       foreach(System.Data.IDataParameter dp in ps)

                       {

                            lst.Add(dp);

                       }

                   }

              }

              Array array = Array.CreateInstance(typeof(System.Data.IDataParameter),lst.Count);

              lst.CopyTo(array);

              return array as System.Data.IDataParameter[];

         }

     }


其實Expression只是一個模板類,它自己本生并沒有條件處理的能力只是一個簡單的1=1;下面我們根據這個模板類派生出具體表達式類型。

/// <summary>

     /// 基礎表達式抽象類

     /// </summary>

     [Serializable]

     public abstract class BaseExpression:Expression

     {

         /// <summary>

         /// 獲取表達式參數對象集

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>System.Data.IDataParameter[]</returns>

         public override System.Data.IDataParameter[] GetDataParams(HFSoft.Data.IDriverType driver)

         {

              System.Data.IDataParameter p1 = driver.GetParameter(Name+ Sequence,Value);

              return ParamsConcat(new System.Data.IDataParameter[]{p1},GetSubParams(driver));

         }

         /// <summary>

         /// 獲取表達式

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>string</returns>

         public override string GetFilter(HFSoft.Data.IDriverType driver)

         {

              System.Text.StringBuilder sb = new System.Text.StringBuilder();

              sb.Append(Name);

              sb.Append(GetCompareType());

              sb.Append(driver.FormatNameForParameter(Name + this.Sequence));

              return sb.ToString();

         }

         /// <summary>

         /// 表達式類型

         /// =,like等

         /// </summary>

         /// <returns>string</returns>

         protected abstract string GetCompareType();

 

 

     }

     /// <summary>

     /// 等于表達式

     /// </summary>

     [Serializable]

     public class EqExpression:BaseExpression

     {

         /// <summary>

         /// 構造等于表達式對象

         /// </summary>

         public EqExpression()

         {

         }

         /// <summary>

         /// 構造指定名稱和值的等于表達式對象

         /// </summary>

         /// <param name="name">名稱</param>

         /// <param name="value">值</param>

         public EqExpression(string name,object value)

         {

              Name = name;

              Value = value;

         }

         /// <summary>

         /// 表達式比較符

         /// </summary>

         /// <returns>string</returns>

         protected override string GetCompareType()

         {

              return " = ";

         }

     }

整個條件對象的設計就完成了,文章代碼中只有實現了等于的表達式對象;我們可以按自己情況編寫更復雜的表達式。條件表達式對象在整個查詢對象中是比較核心的部心,因為在整個SQL查詢語句中除了這些條件外其它地方都是固定的,剩下的就是把些不同的字符串合并起來,這些東西就不詳細說了大家比較了解。

 

其實Expression只是一個模板類,它自己本生并沒有條件處理的能力只是一個簡單的1=1;下面我們根據這個模板類派生出具體表達式類型。

/// <summary>

     /// 基礎表達式抽象類

     /// </summary>

     [Serializable]

     public abstract class BaseExpression:Expression

     {

         /// <summary>

         /// 獲取表達式參數對象集

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>System.Data.IDataParameter[]</returns>

         public override System.Data.IDataParameter[] GetDataParams(HFSoft.Data.IDriverType driver)

         {

              System.Data.IDataParameter p1 = driver.GetParameter(Name+ Sequence,Value);

              return ParamsConcat(new System.Data.IDataParameter[]{p1},GetSubParams(driver));

         }

         /// <summary>

         /// 獲取表達式

         /// </summary>

         /// <param name="driver">數據設備提供者</param>

         /// <returns>string</returns>

         public override string GetFilter(HFSoft.Data.IDriverType driver)

         {

              System.Text.StringBuilder sb = new System.Text.StringBuilder();

              sb.Append(Name);

              sb.Append(GetCompareType());

              sb.Append(driver.FormatNameForParameter(Name + this.Sequence));

              return sb.ToString();

         }

         /// <summary>

         /// 表達式類型

         /// =,like等

         /// </summary>

         /// <returns>string</returns>

         protected abstract string GetCompareType();

 

 

     }

     /// <summary>

     /// 等于表達式

     /// </summary>

     [Serializable]

     public class EqExpression:BaseExpression

     {

         /// <summary>

         /// 構造等于表達式對象

         /// </summary>

         public EqExpression()

         {

         }

         /// <summary>

         /// 構造指定名稱和值的等于表達式對象

         /// </summary>

         /// <param name="name">名稱</param>

         /// <param name="value">值</param>

         public EqExpression(string name,object value)

         {

              Name = name;

              Value = value;

         }

         /// <summary>

         /// 表達式比較符

         /// </summary>

         /// <returns>string</returns>

         protected override string GetCompareType()

         {

              return " = ";

         }

     }

整個條件對象的設計就完成了,文章代碼中只有實現了等于的表達式對象;我們可以按自己情況編寫更復雜的表達式。條件表達式對象在整個查詢對象中是比較核心的部心,因為在整個SQL查詢語句中除了這些條件外其它地方都是固定的,剩下的就是把些不同的字符串合并起來,這些東西就不詳細說了大家比較了解。

http://www.survivalescaperooms.com/niit007/archive/2006/08/13/475581.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿勒泰市| 怀远县| 门源| 长治县| 旌德县| 建水县| 海南省| 龙南县| 吴堡县| 河东区| 台中县| 灵寿县| 海门市| 辽中县| 辽源市| 阿图什市| 额济纳旗| 永寿县| 方城县| 买车| 眉山市| 昔阳县| 兴山县| 莒南县| 临颍县| 贵州省| 吉木萨尔县| 许昌县| 福海县| 辽阳市| 东兰县| 许昌市| 阜平县| 洛川县| 三台县| 山西省| 闸北区| 安阳市| 古田县| 古田县| 敖汉旗|