SqlDataSource中的动态WHERE子句

我在一个非常简单的应用程序中使用SqlDataSource。 我允许用户通过TextBoxes为SDS的select命令设置几个搜索参数,每个参数一个TextBox(想想txtFirstName,txtLastName等)。 我打算使用按钮单击事件处理程序来设置SqlDataSource的SelectCommand属性,默认情况下它将返回所有记录(出于我的目的)。 我想改进这个select命令,可能会添加一个或多个WHERE子句,具体取决于用户是否在我的任何TextBox中输入搜索条件。

我不清楚的例子:

默认情况下,我的SqlDataSource的SelectCommand属性将是这样的:

SELECT * FROM MyTable 

如果用户在txtFirstName中输入“Bob”,我希望SelectCommand属性看起来像这样:

 SELECT * FROM MyTable WHERE [FirstName]='Bob' 

如果用户在txtLastName中输入“Jones”,我希望SelectCommand属性如下所示:

 SELECT * FROM MyTable WHERE [FirstName]='Bob' AND [LastName]='Jones' 

我的问题:
有没有办法动态创建这些WHERE子句,而我不必测试空TextBox并手工构建WHERE子句?

我的小应用程序只有三个参数,因此粗暴强行通过这不会很痛苦,但我想知道是否有更简单的方法来做到这一点加上我可能需要在将来添加更多参数。 另外,我可能想要添加通配符搜索。

如你所说,构建该查询并不困难,因为你总是在where子句中对字段进行AND运算。

请注意,如果您这样做,请不要格式化字符串。 使用SqlParameters来避免SQL注入: http : //en.wikipedia.org/wiki/SQL_injection

因此,您可以从WHERE开始,对于每个具有值的文本框,追加[(fieldName)] = @(fieldname)并绑定该sql参数。

请参阅: http : //msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.aspx

如果您愿意使用Linq to SQL或entity framework,请参阅此谓词构建器: http : //www.albahari.com/nutshell/predicatebuilder.aspx

如果您使用的是SqlDataSource控件,并且参数值来自页面控件,则可以提供ControlParameters并使用带有短路参数的静态where子句。 这可能只是快速敲打一些代码的门票。

        

你可以设置ConvertEmptyStringToNull="false"并执行:

 SELECT * FROM MyTable WHERE [FirstName] = CASE @firstname WHEN '' THEN [FirstName] END AND [LastName] = CASE @lastname WHEN '' THEN [LastName] END 

或者你可以设置ConvertEmptyStringToNull =“true”并执行:

 SELECT * FROM MyTable WHERE [FirstName] = ISNULL(@firstname, [FirstName]) AND [LastName] = ISNULL(@lastname,[LastName]) 

在其中任何一个中,如果用户将文本框留空,则CASEISNULL语句ISNULL where语句的每个部分与其自身进行比较,从而返回TRUE并生成相同的记录,就好像where子句的那部分不在那里一样一点都不 这是一个简单易用的解决方案,可以将查询和参数保持为静态,并将逻辑推送到SQL端。

但是,与仅仅说"SELECT * FROM MyTable"相比,它会产生(小)性能影响。 那些CASEISNULL操作不是免费的;)如果这是一个问题,Bryanmac的解决方案是完全可以接受的。

您可以使用CancelSelectOnNullParameter=false ,如本例所示