2015-06-19 5 views
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 Injection] (https://en.wikipedia.org/wiki/SQL_injection) и как предотвратить его, прежде чем этот код развертывается к производству. –

+0

Рефакторинг. http://www.refactoring.com/catalog/consolidateConditionalExpression.html и http://www.refactoring.com/catalog/consolidateDuplicateConditionalFragments.html – Amit

+0

Пожалуйста, используйте полный верхний регистр для ключевых слов команды, таких как 'SELECT',' FROM' и т. д. on .. Это облегчает понимание команды быстро. :) –

ответ

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

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); 
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)); 

и так далее, а затем построить свой Where придаточного из keyValueList:

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 line) и не нужно менять другой код позже.

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);