多重嵌套的if条件语句

3

我有五个条件需要检查(即用户是否想使用此字段进行搜索)。有四个组合框和一个文本字段。用户可以根据需要使用任何字段或多个字段进行搜索。为了检查用户选择的字段,我构建了几个if和else if语句。但是在仅处理两个条件时,我意识到这对于五个条件来说将是多么繁琐的任务,是否有更好的方法来解决这个问题?

if  (cmbAgent.Text=="")
{
    if (cmbDegree.Text=="")
    {
        OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM UniversityData", connection);
    }
    else
    {
       OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM UniversityData WHERE Expertise LIKE '%" + cmbDegree.Text + "%' ", connection);
    }
}
else if(cmbDegree.Text=="")
{
    OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM UniversityData WHERE SourceOfContact LIKE '%"+ cmbAgent.Text + "%' ", connection);
}
else
{
    OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM UniversityData WHERE SourceOfContact LIKE '%" + cmbAgent.Text + "%' and Expertise LIKE '%" + cmbDegree .Text + "%' ", connection);
}

2
不是针对你的问题的答案,但在将此代码部署到生产环境之前,你应该去阅读一下关于SQL注入以及如何预防它的内容。 - James Thorpe
重构。http://www.refactoring.com/catalog/consolidateConditionalExpression.html和http://www.refactoring.com/catalog/consolidateDuplicateConditionalFragments.html - Amit
2
看起来像是一个比较温和的XY问题。你想要给用户提供什么功能?也许从UI的角度来看,复选框并不是最有效的方式,这样可以简化你的代码,让你完全避免这个问题。 - Adam Houldsworth
2
@MalteR 这是个人口味问题。我所有的 SQL 都是小写字母编写的... - James Thorpe
@JamesThorpe 当然可以。W3C使用全大写,我认为这样更容易看到关键字并理解命令。 - Malte R
显示剩余6条评论
4个回答

3
这就是为什么大多数人单独构建查询/查询字符串的原因。例如:
var sb = new StringBuilder();
sb.Append("Select * from UniversityData where 1 = 1");
if(!string.IsNullOrEmpty(cmbDegree.Text.Trim())){
    sb.Append(" and Expertise like '%" + cmbDegree.Text + "%'")
}
//...
var querystring = sb.ToString();
OleDbDataAdapter da = new OleDbDataAdapter(querystring);

3

如果用户需要/想要输入多个值怎么办?
您可以轻松地动态构建查询。

顺便提一句,您应该使用查询参数来防止SQL注入攻击。

// the "where 1=1" allows to always concatenate "and xxx"
// instead of testing if there were fulfilled conditions before
var query = "SELECT * FROM UniversityData WHERE 1 = 1";

var parameters = new Dictionary<string, string>();

if (txtDegree.Text != "")
{
   query += " AND Expertise like '%' + ? + '%' ";
   parameters.Add("degree", txtDegree.Text);
}

if(txtAgent.Text != "")
{
    query += " AND SourceOfContact like '%' + ? + '%' ";
    parameters.Add("agent", txtAgent.Text);
}

OleDbDataAdapter da = new OleDbDataAdapter(query, connection);
// add the parameters
foreach (var p in parameters) {
    da.SelectCommande.Parameters.Add(p.Key, OleDbType.VarChar, p.Value);
}

请注意,OleDb不支持命名参数。如果可以的话,我建议考虑切换到Sql命令和适配器。
顺便说一下,如果您能/想使用Linq来构建查询(通过Entity Framework或任何其他ORM),也可以这样做,因为Linq和Entity Framework一起是后期绑定的(意味着查询直到实际读取结果时才执行)。
// build the query
var results = from ud in context.UniversityData
              select ud;

if (txtDegree.Text != string.Empty) {
    results = from ud in results
              where ud.Expertise.Contains(txtDegree.Text)
              select ud;
}

if (txtAgent.Text != string.Empty) {
    results = from ud in results
              where ud.SourceOfContact.Contains(txtAgent.Text)
              select ud;
}

// use the results
myControl.DataSource = results.ToList(); // the ToList() call actually calls the query

2
终于有一个正确的方法可以防止 SQL 注入的答案了。 - BigM

2
我会这样做:

我会像这样做:

var query = "Select * from UniveristyData";
var wheres = new List<string>();
if (!cmbDegree.Text.IsNullOrEmpty())
    wheres.Add("Expertise like '%" + cmbDegree.Text + "%'");
if (!cmbAgent.Text.IsNullOrEmpty())
    wheres.Add("SourceOfContact like '%"+cmbAgent.Text+"%'");

if (wheres.Any())
    query += " where " + string.Join(" and ", wheres);

var da = new OleDbDataAdapter(query, connection);

0
你可以先构建一个键值对列表:
List<Tuple<string, string>> keyValueList = new List<Tuple<string, string>>();

keyValueList.Add(new Tuple<string, string>("Expertise", cmbDegree.Text));
keyValueList.Add(new Tuple<string, string>("SourceOfContact", cmbAgent.Text));

然后,您可以根据keyValueList构建Where-Clause:

var conditionsArray = keyValueList.Where(p => !string.IsNullOrWhiteSpace(p.Item2)).Select(q => q.Item1 + " LIKE '%" + q.Item2 + "%'").ToArray();

最后:

var sqlQuery = "SELECT * FROM UniversityData WHERE " + string.Join(" AND ", conditionsArray);

在添加WHERE子句之前,您需要添加检查是否数组为空等检查,但我怀疑您不需要帮助 :-)

要添加更多条件,只需将更多元组添加到keyValueList中(1行),无需稍后更改其他代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接