Поиск по БД УСЛОВИЕ

249
04 июня 2018, 08:10

Ребята, как сделать сам поиск я знаю, запросы и все такое. Помогите мне, возможно ли написать красивое условие если несколько разновидностей поиска? или придется как я пока начал, это несколько(оч. много) else if.

            //По году
        else if (numericUpDownMonth.Value == 0 && textBoxArticle.Text.Equals("") && textBoxFIOSuspect.Text.Equals(""))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(string.Format("Select ID AS 'П/н', NumberCriminalCases AS '№ у/д' , Article AS 'Статья', DateIntination AS 'Дата возбуждения у/д', Subdivision AS 'Подразделение', FIOEmployee AS 'ФИО Сотрудника', NumberCRB AS '№ КУСП', DateCRB AS 'Дата КУСП', Fabula AS 'Фабула', FIOSuspect AS 'ФИО подозреваемого', LimitationDate AS 'Срок' From dbo.ListOfCriminalCases Where YEAR(DateCRB) = {0}", numericUpDownYear.Value), conn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            dgvArchive.DataSource = dt;
            conn.Close();
            numericUpDownMonth.Value = 0;
            tabControlSearch.Visible = false;
        }
        //По месяцу
        else if (numericUpDownYear.Value == 0 && textBoxArticle.Text.Equals("") && textBoxFIOSuspect.Text.Equals(""))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(string.Format("Select ID AS 'П/н', NumberCriminalCases AS '№ у/д' , Article AS 'Статья', DateIntination AS 'Дата возбуждения у/д', Subdivision AS 'Подразделение', FIOEmployee AS 'ФИО Сотрудника', NumberCRB AS '№ КУСП', DateCRB AS 'Дата КУСП', Fabula AS 'Фабула', FIOSuspect AS 'ФИО подозреваемого', LimitationDate AS 'Срок' From dbo.ListOfCriminalCases Where Month(DateCRB) = {0}",numericUpDownMonth.Value), conn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            dgvArchive.DataSource = dt;
            conn.Close();
            numericUpDownMonth.Value = 0;
            tabControlSearch.Visible = false;
        }
        //По году и месяцу
        else if(textBoxArticle.Text.Equals("") && textBoxFIOSuspect.Text.Equals(""))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(string.Format("Select ID AS 'П/н', NumberCriminalCases AS '№ у/д' , Article AS 'Статья', DateIntination AS 'Дата возбуждения у/д', Subdivision AS 'Подразделение', FIOEmployee AS 'ФИО Сотрудника', NumberCRB AS '№ КУСП', DateCRB AS 'Дата КУСП', Fabula AS 'Фабула', FIOSuspect AS 'ФИО подозреваемого', LimitationDate AS 'Срок' From dbo.ListOfCriminalCases Where YEAR(DateCRB) = {0} and Month(DateCRB) = {1}",  numericUpDownYear.Value, numericUpDownMonth.Value), conn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            dgvArchive.DataSource = dt;
            conn.Close();
            numericUpDownMonth.Value = 0;
            tabControlSearch.Visible = false;
        }
        else if (textBoxFIOSuspect.Text.Equals(""))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(string.Format("Select ID AS 'П/н', NumberCriminalCases AS '№ у/д' , Article AS 'Статья', DateIntination AS 'Дата возбуждения у/д', Subdivision AS 'Подразделение', FIOEmployee AS 'ФИО Сотрудника', NumberCRB AS '№ КУСП', DateCRB AS 'Дата КУСП', Fabula AS 'Фабула', FIOSuspect AS 'ФИО подозреваемого', LimitationDate AS 'Срок' From dbo.ListOfCriminalCases Where YEAR(DateCRB) = {0} and Month(DateCRB) = {1} and Article = '{2}'", numericUpDownYear.Value, numericUpDownMonth.Value,textBoxArticle.Text), conn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            dgvArchive.DataSource = dt;
            conn.Close();
            numericUpDownMonth.Value = 0;
            tabControlSearch.Visible = false;
        }

Это еще не конец, придется писать кучу условий пусто то или иное значение.

Попробую описать какие должны быть виды поиска

  1. Поиск по году
  2. Поиск только по месяцу
  3. Году и Месяцу
  4. Году и Статье
  5. Году и ФИО
  6. Месяцу и Статье
  7. Месяцу и ФИО
  8. Году, месяцу и ФИО
  9. Году месяцу и Статье

Даже не знаю, все ли перечислил.

Надеюсь на светлые идеи.

Или я делаю правильно и иначе нельзя?

Можете кинуть свои варианты как вы бы сделали, может я переделаю.

Answer 1

У всех ваших запросов есть общая часть и её можно вынести в отдельную переменную.

Постоянная часть запроса:

Select
    ID AS 'П/н',
    NumberCriminalCases AS '№ у/д',
    Article AS 'Статья',
    DateIntination AS 'Дата возбуждения у/д',
    Subdivision AS 'Подразделение',
    FIOEmployee AS 'ФИО Сотрудника',
    NumberCRB AS '№ КУСП',
    DateCRB AS 'Дата КУСП',
    Fabula AS 'Фабула',
    FIOSuspect AS 'ФИО подозреваемого',
    LimitationDate AS 'Срок'
From dbo.ListOfCriminalCases 
Where 1 = 1

Переменная часть запроса для года:

and YEAR(DateCRB) = {0}

Переменная часть запроса для месяца:

and Month(DateCRB) = {0}

Для года и месяца одновременно:

and YEAR(DateCRB) = {0}
and Month(DateCRB) = {1}

И так далее.

Добавление тавтологического условия 1 = 1 позволяет прицеплять любые переменные части и избавиться от крупных кусков дубликатов кода. У вас появляется более компактный switch...case.

PS Вечно забываю, как этот приём в SQL запросах по-умному называется, может кто подскажет?

PPS И ещё. Внутри каждого if у вас однотипные куски кода - а это значит, что их можно вынести за пределы if и написать всего лишь один раз, а внутри if останется только cmd =. Ну и после этого заменить if на switch.

Образец для примера:

string query = "select ... where 1 = 1";
if(x == 1)
{
   query += "and year = 2017";
   execute(query);
}
if(x == 2)
{
   query += "and month = 01";
   execute(query);
}

можно заменить на:

string query = "select ... where 1 = 1";
if(x == 1)
{
   query += "and year = 2017";
}
if(x == 2)
{
   query += "and month = 01";
}
execute(query);

Логика понятна? У вас всегда внутри if идёт conn.Open() - почему нужно постоянно повторять эту строку, если можно было один раз ДО if написать?

READ ALSO
Entity Framework не отображает свойства

Entity Framework не отображает свойства

Есть два класса Author и Book

236
“Отказано в доступе” при работе с процессами

“Отказано в доступе” при работе с процессами

Обращение ко многим свойствам процессов (включая безобидные StartTime, HasExited) выдают это самое исключениеМного гуглил, но везде рекомендуют от имени...

219
wpf Validation возврат значения в модель

wpf Validation возврат значения в модель

В общем есть такой TextBox к которому добавлены ValidationRules Вопрос в том как правильно вернуть в модель(привязать к модели) флаг о наличии ошибки...

250