наилучшая практика для получения данных, которые соответствуют выбранным условиям - PullRequest
4 голосов
/ 01 ноября 2008

У меня есть таблица базы данных с именем call со столбцами call_time, location, emergency_type, и есть три типа чрезвычайных ситуаций: парамедики, полиция и пожарные. В форме окна я создал CheckBoxes 'paramedics', 'Police', 'firefighters', и я хочу получить все столбцы таблицы, которые соответствуют выбору пользователя.

Я создал функцию:

public static DataTable GetHistory(DateTime from, DateTime to, bool paramedics, bool police, bool firefighters)
    {
        string select =
            "SELECT call_time, location, emergency_type where call_time between @from AND @to AND";
        if(paramedics)
        {
            select += " emergency_type = 'paramedics' ";
        }
        if(paramedics && police)
        {
           select +=" emergency_type = 'paramedics' OR emergency_type = 'police';
        }
        ...

    }

Этот код, однако, кажется очень грязным, потому что, если бы было 30 видов чрезвычайных ситуаций, было бы 30! комбинации, и я бы состарился, прежде чем писать все заявления if.

Буду признателен, если вы поделитесь своей практикой поиска данных, которые соответствуют выбранным условиям поиска, если есть много вариантов, которые вы можете выбрать.

Спасибо!

Ответы [ 4 ]

5 голосов
/ 01 ноября 2008

Что ж, если вам нужно использовать тип_элемента_ чрезвычайной ситуации в качестве строки, тогда вместо передачи значений типа bools вы можете отправить список, содержащий текстовое представление типа аварийной ситуации. Например, чтобы настроить приведенный выше код, вы можете изменить сигнатуру метода на

public static DataTable GetHistory(DateTime from, DateTime to, List<string> types)
{
 ..
}

и затем передайте список, который выглядел следующим образом (например)

List<string> types = 
  new List<string> { "paramedics" };

or 

List<string> types = 
  new List<string> { "paramedics", "police" };

Тогда вы можете адаптировать свой запрос для использования оператора SQL IN в предложении where. Затем преобразуйте список строк в строку, разделенную запятыми, например

string values = "'paramedics', 'police'"

Простой способ создать переменную значений - использовать

string values = string.Empty;
            types.ForEach(s =>
            {
               if (!string.IsNullOrEmpty(values))
                   values += ",";
               values += string.Format("'{0}'", s);

            });

Кстати, вы можете использовать параметризованную команду, чтобы избежать внедрения SQL. Если у вас есть строка, вы можете просто сделать

string select =
 "SELECT call_time, location, emergency_type where call_time between @from AND @to AND emergency_type IN " + values
0 голосов
/ 01 ноября 2008

Создайте пользовательский список значений сравнения (@EmergencyList) и используйте SQL с параметризованным запросом с помощью оператора Contains.

SELECT call_time, 
       location, 
       emergency_type 
where call_time between @from AND @to 
  AND CONTAINS( Emegency_Type, @EmergencyList )
0 голосов
/ 01 ноября 2008

Следует избегать конкатенации строк, так как это может привести к некоторым неприятным уязвимостям. Если вы ищете лучшие практики с точки зрения программного доступа, то здесь лучше всего использовать параметризованный запрос.

Если вы хотите быть дешевым, сделайте так, чтобы предложение in принимало параметр и объединяло эту строку вместе из списка отмеченных флажков и передавало это значение параметра в предложении in. это будет выглядеть так:

where ... and emergency_type in (?)

Другой способ сделать это - подсчитать количество отмеченных флажков и построить список параметров в предложении in, чтобы он выглядел примерно так:

where ... and emergency_type in(?,?...) -- as many params as there are checked checkboxes.

Любой из них будет хорошо. С этими типами запросов я зашел так далеко, что создал собственные методы конструктора SQL, веду внутренний подсчет параметров и их типов данных и динамически собираю sql, а затем выполняю подготовку с известным списком хороших параметров. .

Вы можете посмотреть на изучение Linq.

0 голосов
/ 01 ноября 2008

Это грязный способ сделать это.

string select = "SELECT call_time, location, emergency_type where call_time between @from AND @to AND (1=0";

if(paramedics) { select += " OR emergency_type = 'paramedics' "; }
if(police)     { select += " OR emergency_type = 'police'"; }
if(xyz)        { select += " OR emergency_type = 'xyz'"; }

select += ")";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...