程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#運算符重載實現動太SQL生成

C#運算符重載實現動太SQL生成

編輯:C#入門知識

 

C#提供運算符重載功能,但這功能使用的場合並不多,相信很多C#開發人員雖然了解到有這一功能,但相信用到的比較少.為什麼要自己重載運算符來生成SQL而不去用Linq?其目的也是非常簡單的使用簡單和靈活。先來看一下有多少運算符可以重載:+, -, *, /, %, &, |, ^, <<, >>==, !=, <, >, <=, >=

 

看上去還是挺多的,應該能滿SQL對應的需要,首先整理出一個對應關系

 

c#    SQL

==    =

!=     <>

>      >

>=    >=

<      <

<=    <=

&      and

|       or

 

總得來說基礎的已經差不多了,但決少like,in等,這些可以使用函數或一技巧上的轉換實現.

 

    既然實現運算符重載,那當然就要重建一個對象做他基礎實現,其作用就是類似於SQL中的字段.

 

 

public class FieldInfo

    {

        public FieldInfo(string table, string name)

        {

            DBContext.Init();

            mTable = table;

            mName = name;

        }

        private string mTable;

        public string Table

        {

            get

            {

                return mTable;

            }

        }

        private string mName;

        public string Name

        {

            get

            {

                return mName;

            }

        }

}

     表達一個字段的類型以上描述就足夠了,有所在的表名和字段名.在實現運算符重載前還是把基礎功能用函數實現,運算符重載方法簡單調用就OK了.

 

 

public Expression Eq(object value)

        {

            string p = Expression.GetParamName();

            Expression exp = new Expression();

            exp.SqlText.Append(string.Format(" {0}=@{1} ",Name,p));

            exp.Parameters.Add(new Command.Parameter{ Name=p,

                Value=Mappings.PropertyCastAttribute.CastValue(Table,Name, value)});

            return exp;

        }

        public Expression LtEq(object value)

        {

            string p = Expression.GetParamName();

            Expression exp = new Expression();

            exp.SqlText.Append(string.Format(" {0}<=@{1} ", Name, p));

            exp.Parameters.Add(new Command.Parameter { Name = p,

                Value = Mappings.PropertyCastAttribute.CastValue(Table, Name, value)

            });

            return exp;

        }

        public Expression Lt(object value)

        {

            string p = Expression.GetParamName();

            Expression exp = new Expression();

            exp.SqlText.Append(string.Format(" {0}<@{1} ", Name, p));

            exp.Parameters.Add(new Command.Parameter { Name = p,

                Value = Mappings.PropertyCastAttribute.CastValue(Table, Name, value)

            });

            return exp;

        }

    大體上描述幾個方法實現就行了,對於其他實現原理一樣.下面開始運算重載部分

 

 

public static Expression operator ==(FieldInfo field, object value)

        {

            if (value == null)

                return field.IsNull();

            if (value is System.Collections.IEnumerable && value.GetType() !=typeof(string))

                return field.In((System.Collections.IEnumerable)value);

            return field.Eq(value);

        }

        public static Expression operator !=(FieldInfo field, object value)

        {

            if (value == null)

                return field.IsNotNull();

            if (value is System.Collections.IEnumerable && value.GetType() != typeof(string))

                return field.NotIn((System.Collections.IEnumerable)value);

            return field.NotEq(value);

        }

        public static Expression operator >(FieldInfo field, object value)

        {

            return field.Gt(value);

        }

        public static Expression operator >=(FieldInfo field, object value)

        {

            return field.GtEq(value);

        }

        public static Expression operator <(FieldInfo field, object value)

        {

            return field.Lt(value);

        }

        public static Expression operator <=(FieldInfo field, object value)

        {

            return field.LtEq(value);

        }

    到這裡工作算是完成了,不過好象少了點什麼東西似的...似乎沒有實現&和|;因為這兩個運算不是比較運算符所以不是FieldInfo對象實現的.以上代碼中每個比較運算都返回了一個Expression對象,那&和|自然就由它來實現了

 

public static Expression operator &(Expression exp1, Expression exp2)

        {

            if (exp1 == null || exp1.SqlText.Length == 0)

                return exp2;

            if (exp2 == null || exp2.SqlText.Length == 0)

                return exp1;

 

            Expression exp = new Expression();

            exp.SqlText.Append("(");

            exp.SqlText.Append(exp1.ToString());

 

            exp.SqlText.Append(")");

            exp.Parameters.AddRange(exp1.Parameters);

            exp.SqlText.Append(" and (");

            exp.SqlText.Append(exp2.SqlText.ToString());

            exp.SqlText.Append(")");

            exp.Parameters.AddRange(exp2.Parameters);

            return exp;

        }

        public static Expression operator |(Expression exp1, Expression exp2)

        {

            if (exp1 == null || exp1.SqlText.Length == 0)

                return exp2;

            if (exp2 == null || exp2.SqlText.Length == 0)

                return exp1;

            Expression exp = new Expression();

            exp.SqlText.Append("(");

            exp.SqlText.Append(exp1.ToString());

           

            exp.SqlText.Append(")");

            exp.Parameters.AddRange(exp1.Parameters);

            exp.SqlText.Append(" or (");

            exp.SqlText.Append(exp2.SqlText.ToString());

            exp.SqlText.Append(")");

            exp.Parameters.AddRange(exp2.Parameters);

            return exp;

 

        }

對於以上完整代碼可以從https://smarkdata.svn.codeplex.com/svn/Smark/Smark.Data/Smark.Data/Expression.cs獲取

 

實現代碼的都完成的,那看一下分別在不同查詢的情況下是什麼效果:

 

sql:

 

     select * from customer where region='UK'

 

c#

 

    (Customer.Region=='UK').List<Customer>()

 

sql:

 

    select * from Orders where OrderDate>'1998-7-8' and OrderDate <' 1998-8-8'

 

c#

 

    (Order.OrderDate >"1998-7-8" & Order.OrderDate<"1998-8-8").List<Orders>()

 

sql:

 

    select * from Orders where CustomerID in('2','5','6')

 

c#

 

    (Orders.CustomerID ==new []{"2","5","6"}).List<Orders>();

 

sql:

 

    select * from Orders where CustomerID in(select customerid from customer where region='UK')

 

c#

 

    (Orders.CustomerID==Customer.CustomerID[Customer.Region=="UK"]).List<Orders>();

 

從以上代碼可以看出由於自己重載所以自由度很高,對於==這個運算符可以代替很多SQL的比較操作如:=,in,in(select)等,當然還可以發揮編寫者了想象力.

 

由於是自定義編寫實現,那條件動態組合當然要比Linq所靈活很多:

 

 

Expression exp;

if(a)

   exp &=order.id=="a";

if(b)

   exp &= order.customerid==customer.customerid[customer.region=="b"]

作者:smark

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved