我不知道你为什么使用Request.Form。像if (chkSpice.Checked) 这样的东西会更易读。
如果您必须将 SQL 保存在代码中,并且不能使用存储过程,那么这是您可以做到的一种方法。您不接受用户输入并在 SQL 中传递它,因此不存在 SQL 注入风险。
如果您知道您的样式和颜色将在数据库中命名,SQL IN 运算符会更有效。
string styles = String.Empty;
string colors = String.Empty;
if (chkTapestry.Checked)
styles = "'Tapestry'";
else if (chkRug.Checked)
styles += ",'Rug'";
if (chkBlack.Checked)
colors = "'Black'";
else if (chkBeige.Checked)
colors += ",'Beige'";
string sql = "SELECT * FROM [X]";
if (styles.Length > 0 && colors.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0}) AND [Color] IN ({1})", styles, colors);
else if (styles.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0})", styles);
else if (colors.Length > 0)
sql += String.Format(" WHERE [Color] IN ({0})", colors);
以上是组装样式和颜色的一种相当手动的方法,并且使用了令人遗憾的样式和颜色名称的硬编码。更好的设计可能是:
- 从数据库中选择所有颜色。将它们存储在 DataTable 中。
- Data 将颜色 DataTable 绑定到 CheckBoxList 控件以在页面上显示颜色。
- 从数据库中选择所有样式。将它们存储在另一个 DataTable 中。
- Data 将样式 DataTable 绑定到 CheckBoxList 控件以在页面上显示样式。
然后,在 PostBack 上:
- 使用数据库中的值重新加载您的颜色数据表。接受自您的页面呈现后颜色列表发生变化的小风险,或将 DataTable 跨回发存储在 Session 变量中以降低风险。
- 重新加载您的样式数据表。
- 在 for 循环中遍历您的颜色 CheckBoxList 项。对于选定的每个项目,使用 for 循环索引从 DataTable 中检索相同的行索引。从 DataRow 中获取颜色名称,并将其添加到要在 WHERE 子句的
Color IN (...) 部分中使用的颜色列表中。这可确保您使用的是数据库中的值,而不是可能被用户篡改的值。
- 在 for 循环中遍历您的样式 CheckBoxList 项目,执行与颜色相同的操作。
- 按照我在示例代码中所做的那样组装您的 WHERE 子句。
- 在您的数据库上执行查询并处理结果集。
示例代码:
protected DataTable dtColors
{
get
{
if (Session["fabrics-dtColors"] == null)
Session["fabrics-dtColors"] = FetchDataTable("SELECT DISTINCT Color FROM X ORDER BY Color");
return (DataTable)Session["fabrics-dtColors"];
}
}
protected DataTable dtStyles
{
get
{
if (Session["fabrics-dtStyles"] == null)
Session["fabrics-dtStyles"] = FetchDataTable("SELECT DISTINCT Style FROM X ORDER BY Style");
return (DataTable)Session["fabrics-dtStyles"];
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
cblColors.DataSource = dtColors;
cblColors.DataBind();
cblStyles.DataSource = dtStyles;
cblStyles.DataBind();
}
}
protected void btnSearch_OnClick(object sender, EventArgs e)
{
string colors = String.Empty;
string styles = String.Empty;
string sql = "SELECT * FROM [X]";
if (cblColors.SelectedIndex > -1)
{
for (int i = 0; i < cblColors.Items.Count; i++)
{
if (cblColors.Items[i].Selected)
{
colors += String.Format("'{0}',", dtColors.Rows[i][0]);
}
}
colors = colors.TrimEnd(',');
}
if (cblStyles.SelectedIndex > -1)
{
for (int i = 0; i < cblStyles.Items.Count; i++)
{
if (cblStyles.Items[i].Selected)
{
styles += String.Format("'{0}',", dtStyles.Rows[i][0]);
}
}
styles = styles.TrimEnd(',');
}
if (styles.Length > 0 && colors.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0}) AND [Color] IN ({1})", styles, colors);
else if (styles.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0})", styles);
else if (colors.Length > 0)
sql += String.Format(" WHERE [Color] IN ({0})", colors);
GetSearchResults(sql);
}