Как сделать поиск в windows forms c

Обновлено: 02.07.2024

Я показываю некоторые результаты таблицы SQL в виде сетки данных в приложении Winforms. Я обычно использую DbEntities, но мне пришлось использовать соединение в моем запросе, чтобы получить результаты из нескольких результатов, поэтому вместо этого я использовал этот код.

И я хочу добавить запрос и текстовое поле для результатов поиска при наборе текста. Как я могу сделать это из того, что я уже начал?

3 ответа

Нашел этот ответ для поиска в DataTable.

Таким образом, для вашего решения вам необходимо реализовать

И тогда вы можете использовать его в вашем changeevent:

ОДНАКО: если вы сделаете это, это приведет к большому количеству трафика на ваш sql сервер. Я настоятельно рекомендую вам также внедрить некоторую форму кеша для получения всех доступных для поиска данных. Если это вариант.

Просто чтобы добавить к вопросу и будущему аналогичные проблемы:

Не используйте SQL в качестве «insta-search» для текстовых свойств. Это плохо по многим причинам, как люди, упомянутые выше. Но, во-первых, у вас могут быть проблемы с блокировкой таблиц SQL, из-за которых люди пытаются что-то искать и генерируют много трафика, как следствие, и даже для одного пользователя, что небезопасно и недружественно для ресурсов. Кроме того, у вас высокий трафик. для инъекции SQL. Есть некоторые хорошие методы программирования, чтобы сделать это более безопасным, я попытаюсь объяснить немного больше.

Хорошо, вы уже знаете эту часть информации. Но как правильно сделать это?

Используйте объекты, DAL и кеш-информацию, пока она не станет достаточно старой и придется ее обновлять.

Прежде всего, вы должны создать класс DAL / DAO, который будет использоваться ТОЛЬКО для SQL-запросов и операций. Сделайте поиск по этой теме, и почему плохая идея иметь свои бизнес-правила и шифрованный код. Вот краткий текст об этом: О DAL / DAO

Затем создайте класс объектов. Например: PersonelInfo. Который содержит каждый атрибут, который вам нужен, например: имя, документы и т. Д.

После того, как ваш объект будет создан и готов, используйте списки для хранения и передачи его в datatable или непосредственно в datagridview, если хотите.

Затем используйте цикл, чтобы перебрать данные SQL и заполнить ваш список.

В конце верните свой список объектов:

Таким образом, у вас есть полный организованный список объектов, который вы можете:

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

Обратите внимание, что не все данные безопасны, чтобы сохранить этот путь. Пароли и защищенные материалы не должны храниться в памяти или другими способами, которые могут быть использованы.

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

Часто необходимо узнать длину строки, например, для проверки ввода пользователя. Класс String предоставляет свойство Length, которое дает нам эту информацию. Свойство возвращает целое число, представляющее количество символов.

Примечание: свойство Length выполняется довольно быстро. При проверке строки на пустоту более эффективно проверять нулевую длину, чем сравнивать строковое значение со String.Empty или"".

Поиск позиции текста в строке

На одном из предыдущих уроков мы рассмотрели метод Substring, который позволяет извлекать символы из заданной позиции в строке. Обратное ему - указать ряд символов и определить позицию, в которой подстрока появляется в строке. Это может быть достигнуто с помощью методов IndexOf и LastIndexOf.

IndexOf принимает параметр, содержащий подстроку для поиска. Если она существует в основной строке, возвращается позиция первого вхождения. Эта позиция называется указателем: целое число, указывающее количество символов между началом строки и найденным текстом. Для начала строки этот индекс равен нулю. Если подстрока не находится в основной строке, метод возвращает -1.

LastIndexOf похож на IndexOf. Однако вместо возврата индекса первого вхождения поискового термина LastIndexOf возвращает позицию последнего вхождения.

Указание границ поиска

IndexOf и LastIndexOf могут быть ограничены с указанием начальной позицию для поиска. С IndexOf можно найти только вхождения указанной подстроки справа или справа от этой позиции. При использовании LastIndexOf находятся только соответствующие подстроки слева от этой позиции.

Поиск может быть ограничен третьим параметром. Этот параметр представляет собой целое число, указывающее максимальное количество символов, которые могут быть рассмотрены. Если совпадение не существует в диапазоне символов, то результат будет равен -1.

Простые проверки на содержание

IndexOf и LastIndexOf полезны при определении точного положения подстрок в строках. Однако, иногда достаточно просто знать, что там имеется такая подстрока. Класс String предоставляет несколько методов для выполнения этих тестов.

StartsWith и EndsWith

StartsWith и EndsWith позволяют определить, начинается или заканчивается строка определенной серией символов. Оба метода принимают аргумент, содержащий строку для поиска соответствия, а возвращают логическое значени. Эти методы учитывают регистр.

Т.е. что-от на пример:

DataTable dt = new DataTable();
.
.

DataRow[] dr = dt.Select(Colum_name + " LIKE '" + value + "*'");
int row_index = dt.Rows.IndexOf(dr[0]);

В дот НЕТе недавно, до этого 5 лет был в делфях. Начал работать с БД (АДО дот НЕТ), модель конечно отличается от делфефской, но тем не менее, жить можно)) Такой вопрос (непосредственно связанный с поиском):

как я понял, поиск можно сделать используя:
1) DataView - но только по ключу сортировки, что меня не устраивает, мне нужно запись при текущем положении строк;
2) DataTable - метод Select. Возвращает набор найденных строк, но он не может позиционировать строку в гриде.
3) BindingSource - метод Find и свойство Position делают всё как мне нужно, при этом используется результат выполнения п.2.

Это пока, что смог найти и узнать о поиске данных в дот НЕТ. Если у кого есть ещё варианты, буду рад выслушать.

Теперь пример того, как я делаю:

- раз, поиск и позиционирование только ч/з биндинг, то его и нужно ставить в датаСорс грида

но результат может возвращать более одной строки, следовательно, нужно реализовать метод FindNext. Эту проблему я также обошел, создал класс поиска, он сохраняет результат поиска DataRow[], а затем, при вызове метода FindNext, увеличиваем наш индекс (в коде выше, было указано 0, т.е. первую берем запись).

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

В Вашем вопросе меня смутила вот эта фраза

как у Вас увязана фильтрация и позиционирование?

как у Вас увязана фильтрация и позиционирование?
значит вот что получается, кстати нашел небольшой глюк (хотя может это я глючу, об этом чуть позже): есть набор записей возвращаемый вьюхой (порядка 15 столбцов, некоторые видимые, некторые нет, нам это не сильно интересно). Пользователь захотел сделать поиск, например, по фамилии, нажимает Ctrl+F (хот-кей на пункт меню) и указывает фильтр поиска, он точно не знает, как оканчивается фамилия человека, допустим он вбил "Ивано". Использование метода BindingSource.Find напрямую отпадает, т.к. там только точное совпадение, следовательно идем в обход, берем метод DataTable.Select. Данный метод поможет больше, ведь в него можно передать like конструкцию. Метод Select возвращает набор DataRow, это и понятно, ведь это лайк, совпадений может быть и 1 и 2 и 102. А вот теперь можно и методом Find воспользоваться, ведь в нашем распоряжении теперь полные записи удовлетворяющих нас строк. Вызываем Find передав в качестве key'я DataRow[0], почему 0? Потому что первая запись в полученном списке. Следующий плюс, что нам дает данная конструкция, пользователя не удовлетворила эта первая (нулевая) запись, он хочет "Поиск далее" вызвать, тут на помощь нам приходит наш набор DataRow, снова вызываем метод Find, но в качестве key'я передаем DataRow[1], т.е. следующая запись в наборе результатов поиска и т.д. Как только дошли до конца набора, счетчик на 0 и позиционирование на первую запись. Все просто, как я вижу. Единственный косяк был в том самом наборе результатов поиска, он возвращался почему то в отсортированном виде, пока я не стал подавать методу Select доп. пар-р уточняющий сортировку. Следовательно, до этого, если грид отсортирован, допустим, по сумме, то метод FindNext (реализованный мной) скакал то вверх то вниз, ведь сортировка по фамилии была. После введения пар-ра сортировки, все нормально.

С точки зрения интерфейса - не лучшее решение, но и несложное. Поэтому, когда коллега МСУ выкладывал здесь на форуме код для ввода значения фильтра прямо в заголовке столбца грида, я его сразу скачал. Пока не посмотрел, так как не было необходимости. Это что-то типа фильтров Excel и Access (по крайней мере - старых версий).

У Вас несколько иной подход, но подумайте - удобен ли он для пользователя? Опять же ничего не мешает и при Вашем подходе после ввода каждой буквы в окошке фильтра сразу применять текущее значение.

С точки зрения интерфейса - не лучшее решение, но и несложное. Поэтому, когда коллега МСУ выкладывал здесь на форуме код для ввода значения фильтра прямо в заголовке столбца грида, я его сразу скачал. Пока не посмотрел, так как не было необходимости. Это что-то типа фильтров Excel и Access (по крайней мере - старых версий).

Диалоговое окно Построитель условий поиска применяется для автоматического создания интерфейса поисковой системы на существующей форме на сонове параметризованного запроса на SQL.

Пример. Пусть необходимо создать пользоватьельский интерфейс для поиска данных о сотруднике по фамилии. Для этого необходимо:

Создать DataGridView для таблицы, по которой будет вестись поиск.

В меню «Задачи» к DataGridView выбрать команду «Добавить запрос»:


В открывшемся окне прописать имя нового запроса, например FindFio и нажать кнопку «Построитель запроса…».


В следующем окне к уже имеющейся команде добавить предложение «Where поле=@переменная».

Нажать кнопку «Выполнить запрос», ввести значение параметра и нажать кнопку ОК.


Если, созданный запрос не содержит ошибок, то его результаты появятся в окне Построителя запроса:


Нажать кнопку ОК.

В результате появится панель инструментов для поиска:


В области компонентов появится новый компонент FindFioToolStrip. Названия полей на форме и расположение панели поиска можно поменять, например:


Если созданная панель поиска не устраивает, то:

Удалите панель поиска.

Создайте на форме необходимый элемент управления, например, текстовое поле, для ввода параметра поиска.

Пропишите по кнопке поиска команду:

this.Адаптер.Метод_поиска(this.БД.таблица, искомое значение);

this.personTableAdapter.FindFio(this.sotrudnicDataSet1.person, textBox1.Text);

Изменение запроса

Изменить созданный запрос можно одним из следующих способов:

В меню «Задачи» к Адаптеру таблицы, например, personTableAdapter, выбрав команду «Изменить запросы в конструкторе наборов данных…»


В контекстном меню к таблице выбрав команду «Настроить…»


Поиск по неполному значению

Если необходимо осуществить поиск в строковых полях по неполному значению, то предложение WHERE должно выглядеть следующим образом:

«Where поле like @переменная»

Поиск по нескольким значениям

Если необходимо осуществить поиск по нескольким полям, то предложение WHERE должно выглядеть подобно следующему:

«Where (условие1) and (условие2)»

Восстановление всех записей в таблице

Если необходимо скрыть результаты поиска и отобразить все данные таблицы, то следует прописать команду:

this.Адаптер.Fill(this.БД.Таблица);

this. personTableAdapter.Fill(this.sotrudnicDataSet1.person);

Сортировка

Для сортировки данных в таблице по одному определенному полю следует применять команду:

Источник.Таблица ;

if (comboBox1.Text=="фамилия") personBindingSource.person="fio Desc";

Для указания направления сортировки применяют ключевые слова: Desc – сортировка по убыванию, Asc – сортировка по возрастанию.

Агрегирование

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

Открыть конструктор данных, например, выбрав в контекстном меню к БД в окне Источники данных команду Изменить набор данных в конструкторе:


Если таблица запросов (DataTable) отсутствует, то создать ее. В нашем примере это таблица All.

Через контекстное меню к таблице запросов выбрать команды Добавить, Запрос…


В следующем окне нажать кнопку Далее:


В следующем окне выбрать команду «Инструкция Select, возвращающая одиночное значение» и нажать кнопку Далее


В следующем окне нажать кнопку «Построитель запросов»


В следующем окне необходимо прописать запрос SQL, например:

Select функция(поле) AS имя_результата

From таблица


Замечание. Все поля должны быть выключены.

Для проверки созданного запроса можно нажать кнопку «Выполнить запрос». Если ошибки отсутствуют, то в появившемся окне проверки запроса следует нажать кнопку «ОК», а в окне Построитель запросов – кнопку «Далее».

В окне Выбор имени функции следует ввести имя для новой функции агрегирования и нажать кнопку «Далее».


Убедиться в правильности действий, «Готово»


Вызвать метод на форме, например:

label8.Text = this.allTableAdapter.Avg_sal().ToString();


1) Если запрос должен возвращать больше одного значения, то на шаге пятом следует выбрать команду «Запрос Select, возвращающий строки»

2) Если необходимо посчитать функцию агрегирования для определенной совокупности строк, то следует усложнить запрос:

Select функция(поле) As название результата

From таблица

Where поле=@перем

При этом изменится вызов

label4.Text =this.Адаптер.Avg_sal(значение).ToString();

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Читайте также: