1

ASP.NET 4.0、Web 表单、C#、SQL

我几乎有一些类似于你在约会网站上看到的搜索表单。多个下拉框,每个 ddbox 都有特定的值以及“任何”值。我想不出一种简单的方法来在下面的示例之外创建此语法,并在按钮单击事件后面的 c# 代码中使用大量 else if 语句:

if
= && = && =
else if<br/>
= && = && !=
else if<br/>
= && != && != 
else if<br/>
!= && = && !=

...这是具有选定值的相同序列

if
Any && Any && Any
else if
Any && Any && Not Any
else if
Any && Not Any && Not Any
else if
Not Any && Any && Not Any

这种情况一直持续到我遍历所有场景。在按钮上单击后面的代码将采用选定的值并决定执行哪个查询。似乎导致头痛的是 ddbox 中的值“any”。有没有一种首选的方法来构造 c# 或 sql 语法以减少 else if 的数量?

让我知道这是否有意义或您是否需要更多信息。

4

2 回答 2

2

我会写这样的东西:

create procedure usp_search (
    @param1 varchar(50) = null
   ,@param2 carchar(50) = null
) as
begin
    select field1
          ,field2
          ,field3
          ,fieldN
      from table t with(nolock)
     where ((@param1 is null) or (t.fieldX == @param1))
       and ((@param2 is null) or (t.fieldY == @param2))
end

然后在你的客户上你喜欢

//code
var connection = new SqlConnection("connection_string");
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = "usp_Search";
command.CommandType = CommandType.StoredProcedure;
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1;
}
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2;
}
// code

沿着这些思路......这样您的搜索查询可以检索过滤或未过滤的结果......当然,您必须注意此类查询的一些陷阱

编辑:仅在 C# 代码中完成的相同操作将是这样的:

var sb = new StringBuilder();
sb.Append("select field1 ,field2, field3, fieldN ");
sb.Append("from table t with(nolock) ");
sb.Append("where ((@param1 is null) or (t.fieldX == @param1))");
sb.Append("and ((@param2 is null) or (t.fieldY == @param2))");

var connection = new SqlConnection("connection_string");
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = sb.ToString();
command.CommandType = CommandType.Text;
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1;
}
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2;
}
于 2012-04-18T23:24:35.160 回答
0

首先,我建议在您的下一个项目中考虑使用 ORM,因为动态 sql 在应用程序设计方面有很多此类警告。

也就是说,我处理这个问题的方式是将任何可选的搜索词放在括号内,这样我就可以这样做:

(SomeField = 'Blah' OR 1=1)

请记住,我并不是说这是一个好的解决方案,但它确实允许您减少嵌套语句的数量,因为您可以按顺序构造 SQL 语句。

考虑以下代码:

SQL = "SELECT CompanyName, CompanyState FROM Companies WHERE ";
SQL += "(CompanyName = '" & CompanyName & "' " + (CompanyName == "AnyKey" ? " OR 1=1" : "") + ") ";
SQL += "(CompanyState = '" & CompanyState & "' " + (CompanyState == "AnyKey" ? " OR 1=1" : "") + ") ";

再次,我强调这不应该被认为是好的。我已经转向 ORM,所以我不再有这个问题了。和往常一样,一定要清理你的用户输入。

希望这可以帮助。

于 2012-04-18T23:23:39.873 回答