博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用操作符重载,生成ORM实体类的SQL条件语句
阅读量:5996 次
发布时间:2019-06-20

本文共 3630 字,大约阅读时间需要 12 分钟。

ORM框架的一个不可或缺的功能就是根据实体类,生成操作数据库的SQL语句,这其中,最难处理的就是那些复杂的SQL条件比较语句。比如,有下面这样一个SQL语句:

 

SELECT 
[
id
],
[
BankCode
],
[
CityCode
],
[
FundCode
],
[
FundName
],
[
FundReviews
],
[
EndDagte
],
[
addDate
]
 
FROM 
[
FundReviews
]
    
WHERE  ( 
             (
[
CityCode
]
=
@CP1 
OR 
[
BankCode
]
=
@CP2)  
        
AND  (
[
FundCode
]
=
@CP3 
OR 
[
BankCode
]
=
@CP4
           )

这个复杂的查询条件由两个OR子条件最后组合成一个AND 条件的,因此它有3组条件:

1:[CityCode]=@CP1 OR [BankCode]=@CP2;

2:[FundCode]=@CP3 OR [BankCode]=@CP4;

3:1 AND 2 ;

而条件1其实就是 Condition1 OR Condition2,这又是一个条件组合。

我们发现,尽管SQL的条件语句可能很复杂,但这些条件却是由一些子条件组合成的,或者说由一组条件组合成一个新的条件,大家想想,这是不是典型的“组合模式”阿?

 

在PDF.NET框架的ORM组件中,有一个专门处理条件的对象OQLCompare ,它就是根据“组合模式”设计的,我们来看看怎么由它来构造这个查询条件:

1,采用AND,OR重载:

 

FundReviews p = 
new FundReviews();
//
实例化一个实体类
OQL q = 
new OQL(p);               
//
实例化一个OQL对象
Console.WriteLine(
"
OQLCompare 复杂比较条件表达式测试---------
");
OQLCompare cmp = 
new OQLCompare(p);
OQLCompare cmpResult = (cmp.Comparer(p.CityCode, OQLCompare.CompareType.Equal, 
"
021
")
                | cmp.Comparer(p.BankCode, OQLCompare.CompareType.Equal, 
"
008
"))
                & (cmp.Comparer(p.FundCode, OQLCompare.CompareType.Equal, 
"
KF008
")
                | cmp.Comparer(p.BankCode, OQLCompare.CompareType.Equal, 
"
008
"));
           
q.Select().Where(cmpResult);
Console.WriteLine(
"
SQL=
" + q.ToString());

 

在OQL中,采用了类似SQL的语法,也是

 

Select(
[
属性列表
]).
Where(
[
条件表达式
]).OrderBy(
[
排序字段
]).GroupBy(
[
分组字段
]

 

其中[条件表达式]就可以使用OQLCompare对象来构造。由于OQLCompare对象Comparer函数返回的仍然是一个OQLCompare对象,所以可以利用这个特点,采用组合模式,构造出非常复杂的SQL条件语句。

 

我们看到OQL采用了类似函数式的语法风格,但在[条件表达式]的构造过程中,还是显得很冗长,我们可以继续对OQLCompare对象进行重构:

 

     
///
 
<summary>
        
///
 设置等于某个实体属性的比较条件
        
///
 
</summary>
        
///
 
<param name="compare">
当前实体比较对象
</param>
        
///
 
<param name="Value">
要比较的值
</param>
        
///
 
<returns>
构造的实体比较对象
</returns>
        
public 
static OQLCompare 
operator ==(OQLCompare compare, 
object Value)
        {
            
return BuildOperator(compare, Value, 
"
 = 
");
        }
        
///
 
<summary>
        
///
 设置不等于某个实体属性的比较条件
        
///
 
</summary>
        
///
 
<param name="compare">
当前实体比较对象
</param>
        
///
 
<param name="Value">
要比较的值
</param>
        
///
 
<returns>
构造的实体比较对象
</returns>
        
public 
static OQLCompare 
operator !=(OQLCompare compare, 
object Value)
        {
            
return BuildOperator(compare, Value, 
"
 <> 
");
        }
     
///
 
<summary>
        
///
 根据实体对象的属性,获取新的条件比较对象
        
///
 
</summary>
        
///
 
<param name="field"></param>
        
///
 
<returns></returns>
        
public OQLCompare Property(
object field)
        {
            OQLCompare cmp = 
new OQLCompare();
            cmp.CompareString = 
this.currPropName ;
            
return cmp;
        }
        
private 
static OQLCompare BuildOperator(OQLCompare compare, 
object Value,
string operatorString)
        {
            
string paraName = compare.GetNewParameterName();
            compare.CompareString += operatorString + paraName;
            compare.compareValueList.Add(paraName.Substring(
1), Value);
            
return compare;
        }

 

我们可以采用类似的方式,继续实现 >=,>,<=,< 等SQL条件比较符号的重载,这里就不一一举例了,我们来看新的使用方式:

2,采用SQL比较符号的重载:

 

//
对象 p 为实体类
OQLCompare cmp2 = 
new OQLCompare(p);
OQLCompare cmpResult2 = 
               ( cmp2.Property(p.CityCode) == 
"
021
"  | cmp2.Property(p.BankCode) == 
"
008
")
               &  
               ( cmp2.Property(p.FundCode) == 
"
KF008
"| cmp2.Property(p.BankCode) == 
"
008
");
q.ReSet();
//
重新初始化OQL
q.Select().Where(cmpResult2);
Console.WriteLine(
"
操作符重载 SQL=
" + q.ToString());

 

 

现在这个SQL条件的构造过程是不是清晰多了?这就是操作符重载的魅力:)

 

3,使用Equal方法,简化相等比较

直接看下面的代码,功能跟上面的例子一样:

 

//
对象 p 为实体类
OQLCompare cmp2 = 
new OQLCompare(p);
OQLCompare cmpResult2 = 
               ( cmp2.Equal(p.CityCode,
"
021
")    | cmp2.Equal(p.BankCode,
"
008
")  )
               &  
               ( cmp2.Equal(p.FundCode,
"
KF008
")  | cmp2.Equal(p.BankCode,
"
008
")  );
q.ReSet();
//
重新初始化OQL
q.Select().Where(cmpResult2);
Console.WriteLine(
"
操作符重载 SQL=
" + q.ToString());

从性能上来说,这种方式效率稍高,因为它是函数式的处理方式,更直接。

-------------------------------------------------------------------------

 

注:本文介绍的这个OQL特性仅在PDF.NET Ver 4.3版本受支持,但之前的版本参照本文说的方法加以改进,也可以使用。有关PDF.NET的版本信息,请看官网介绍:

有关PDF.NET的开源信息,请参看我的博客文章:

 

 

 

转载地址:http://kmmlx.baihongyu.com/

你可能感兴趣的文章
BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
查看>>
墨卡托投影、高斯-克吕格投影、UTM投影及我国分带方法
查看>>
Android中通过反射来设置Toast的显示时间
查看>>
Vysor Pro破解助手
查看>>
翻译Beginning iOS 7 Development中文版
查看>>
理顺FFT
查看>>
003-spring结合java类调用quartz
查看>>
Idea 常用功能汇总,工作中常用技巧,移出请说明原因,笔记花了好长时间汇总的...
查看>>
php给图片加入文字水印
查看>>
iOS开发-sqlite3使用
查看>>
(5)QlikView中的RowNo()函数
查看>>
SiteMesh2-示例工程
查看>>
poj 1087 A Plug for UNIX 【最大流】
查看>>
Phoenix与Squirrel 是什么?
查看>>
Photoshop制作的ico图标方法
查看>>
HDU 1241 Oil Deposits (DFS)
查看>>
【翻译自mos文章】注意: ASMB process exiting due to lack of ASM file activity
查看>>
Linux 线程浅析
查看>>
ucgui界面设计演示样例2
查看>>
蓝桥杯练习系统——基础练习 十六进制转十进制
查看>>