select * from V_view1 where ((ISNULL(@varGRNO,'')<>'' and BOLNR=@varGRNO ) or (1=1))
这个方法虽然一定程度上减少了代码量,但是把业务逻辑混杂在Sql语句中,个人感觉不是太好的方法,而且大大增加了维护的难度。当然,有兴趣的同学可以
自己去研究。
既然,以上方法都有弊端,那么有没有更好一点的解放方案呢?答案是肯定的,上次用EF的时候突然想到.Net中的扩展方法能够对这个问题进行优化。
首先,来看一下什么事扩展方法,一下是来做MSDN的解释:
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
我们常用的Linq中引用的 using System.Linq 其实就是一个扩展方法库,更详细的内容可以参照MSDN和c# 扩展方法奇思妙用(鹤冲天)。在这里,我只举一个简单的例子:
比如,正常情况下判断一个字符串是否为空是这样写:
复制代码 代码如下:
string.IsNullOrEmpty(str);
如果加上一个我们自己扩展的方法:
/// <summary>
/// 检查字符串是否是空(IsNullOrEmpty)
/// </summary>
/// <param></param>
/// <returns></returns>
public static bool IsNullOrEmpty(this string str)
{
return string.IsNullOrEmpty(str);
}
那么以后判断字符串是否为空就可以这样:
复制代码 代码如下:
str.IsNullOrEmpty();
是不是简洁、优雅了许多呢?
好,回到正题,看看如何用扩展方法的特性来优化Sql语句的拼接问题。既然扩展方法允许我们以实例方法的方式来调用静态方法,那么我们是否可以给Sql语句的字符串实例扩展一个方法来对其操作呢?
比如这个Sql:
复制代码 代码如下:
StringBulider sbSql=new StringBulider();
sbSql.Append("select * from V_view1 where 1=1 ");
if(!string.IsNullorEmpty(varGRNO))
sbSql.AppendFormat(" and BOLNR = '{0}' ",varGRNO);
实际上就是对一个变量进行判断,然后操作字符串实例。
那么,我们就加行一个这样的扩展:
复制代码 代码如下:
public static string strEquals(this string strSql, string strValue, string ColName)
{
if (!string.IsNullOrEmpty(strValue))
return string.Format(strSql + " and {0}='{1}' ", ColName, strValue);
else
return strSql;
}
看到没有,在方法内部进行参数的非空判断,那么,上面的代码就可以这样写:
复制代码 代码如下:
String strSql="select * from V_view1 where 1=1"
strSql=strSql.strEquals(varGRNO,BOLNR)
是不是少了很多代码?
如果有更多的参数,我们可以写的想Linq一样优雅:
复制代码 代码如下:
String strSql="select * from V_view1 where 1=1"
.strEquals(varGRNO,BOLNR)
.strEquals(varPLNO,VBELN)
.strEquals(varPONO,EBELN)
对于like语句,进行下面的扩展
复制代码 代码如下:
public static string strLike(this string strSql, string strValue, string ColName)
{
if (!string.IsNullOrEmpty(strValue))
return string.Format(strSql + " and {0} like '%{1}%' ", ColName, strValue);
else
return strSql;
}
和范围的扩展:
复制代码 代码如下:
public static string strEqualsOrBetween(this string strSql, string strStart, string strEnd, string ColName)
{
if (string.IsNullOrEmpty(strStart) && string.IsNullOrEmpty(strEnd))
return strSql;
else if (!string.IsNullOrEmpty(strStart) && !string.IsNullOrEmpty(strEnd))
{
return strSql.strBigger(strStart, ColName).strSmaller(strEnd, ColName);
}
else if (string.IsNullOrEmpty(strStart) && !string.IsNullOrEmpty(strEnd))
return strSql.strEquals(strEnd, ColName);
else
return strSql.strEquals(strStart, ColName);
}
这样一来,上面一大段的代码就可以写成这样:
复制代码 代码如下: