我有五个条件需要检查(即用户是否想要使用此字段进行搜索)。有四个组合框和一个文本字段。用户可以根据需要使用任何字段或多个字段进行搜索。要检查用户选择了哪个字段,我构建了几个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);
}
答案 0 :(得分: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);
答案 1 :(得分: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 :(得分: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);
答案 3 :(得分: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-Clausevar 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行)添加更多元组,而不需要在以后更改其他代码。