【原创】ASP.NET中SqlDataSource控件Filter机制实例浅析

实例描述:

SqlDataSource控件的FilterParameters属性中设置三个参数,分别绑定到两个textbox和一个dropdownlist,通过这三个控件中的值作为过滤条件来对SDS的DataSet查询进行过滤,并在GridView中实时体现出来。过滤表达式如下形式:FilterExpression="a1 like '%{0}%' and a2 like '%{1}%' and a3 like '{2}'".

预期情况是,页面加载后下三个提供过滤参数的控件中的值都为空,不对查询进行任何过滤的,将SelectCommend执行结果的数据集在GridView完全体现出来。当输入或改变任何一个提供过滤参数的控件中的值后,能够实时的反映过滤结果,并在GridView中体现出来。

那么实际情况上出了一点偏差,三个控件中有任何一个值为空,整个过滤条件都不发挥作用。

问题分析:

SqlDataSource有个bool属性CancelSelectOnNullParameter:如果设为True,在执行Select时,任意一个查询条件参数值为Null时跳过整个Where子句;

FilterParameters属性集合中的任意参数值中有这样一个bool属性ConvertEmptyStringToNull,并且默认值为True:顾名思义很容易理解,当给定的参数值为空串时,转换它为Null;

FilterParameters属性集合中的任意参数值中还有个DefaultValue:参数值为Null时使用默认值;

那么问题看似是找到了,任选一个解决方案尝试吧:

1.将CancelSelectOnNullParameter设为False?可惜不行,一点效果也没有。是因为这个参数只能负责SelectCommand,Filter机制下CancelSelectOnNullParameter默认即为True并且不能提供更改? or 此为VS2010目前版本存在的Bug? 以上均为猜测就不得而知了。

2.将ConvertEmptyStringToNull设为False?这样未设置过滤值的参数会传一个空串而不是Null,过滤条件将会执行。看似完美的解决方案,可惜有局限性,如果FilterExpression中使用如a1='{0}'这种格式,实际过滤条件就变为a1='',那你就只能查到字段a1为空串的情况了;你说用的是like方式?也不完满,like ''与=''实际效果一样的;要想用这种解决办法,你只能保证你的过滤格式形如like '%{0}%',至少要带一个‘%’。

3.将ConvertEmptyStringToNull设为True,并设置默认为'%';与方法2类似,但可以支持like '{0}'这样的格式。

4.从网友那里新了解到的一种方法,用“*”作为默认值,用法及效果同方法3。

5.你说FilterExpression一定要用a1='{0}'这种格式怎么办?那么最好的办法一定放在后面^_^

  首先,将ConvertEmptyStringToNull设为False;

  然后,FilterExpression改写为形如 FilterExpression="('{0}'='' or a1 ='{0}') and ('{1}'='' or a2 ='{1}') and ('{2}'='' or a3 ='{2}')"

  保存,再去试试吧。看到成效没有?

写在后面的话:

用“*”作为默认值代替“%”的方法我也是这个情况下才知道的,问了很多朋友都没人注意过这种用法,个人推断应该是System.Data中做了转义。千万不要认为是Sql语句本身就支持,标准的SQL-92是用“%”来匹配任意字符串的。如果你用like '*'这样的方法到Sql Server中做模糊查询,那一定得不到你想要的。

顺便再多说一句吧:

在Sql Server中,标准的条件查询是用“%”来匹配任意字符串,用“_”来匹配任意一个字符的;

而在Access中,使用“*”代替“%”来做字符串通配符,“?”代替“_”做字符通配符。不过很遗憾地说,这并不是标准SQL