Dynamiczne wyszukiwanie w bazie
Niedawno zacząłem się zastanawiać nad możliwością dynamicznego przeszukiwania bazy danych w programach pisanych w C#. Chodziło o to aby podczas wpisywania kolejnych liter do pola tekstowego były pobierane wszystkie rekordy zawierające w odpowiednim polu wpisany ciąg znaków. Udało się to zrealizować już w pierwszym testowym programie.
Sposób, który wybrałem polega na wysyłaniu nowego zapytania SQL do bazy za każdym razem kiedy występuje zdarzenie TextChanged kontrolki TextBox.
Z pierwszych testów wynika, że przy bazie lokalnej (Postgressql zainstalowany na tym samym komputerze co uruchamiany program) nie występuje żadne dostrzegalne opóźnienie. Prawdopodobnie sytuacja nie powinna się zmienić przy bazie w sieci lokalnej, co jest sytuacją wystarczającą jeśli chodzi o projekty, w których zamierzam wykorzystać tą technikę. Ale ten scenariusz zapewne zbadam dogłębniej innym razem.
Jak już wspomniałem wykorzystuję relacyjną bazę danych Posgressqsl. Do łączenia się z tą bazą z poziomu c# używam biblioteki Npgsql2 (download).
Poniżej kod z pliku Form1.cs, reszta projektu to kod wygenerowany przez Visual Studio dlatego nie jest tutaj zamieszczony:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Npgsql; namespace LiveSearchTest1 { public partial class Form1 : Form { NpgsqlConnection conn; //obiekt reprezentujący połącznie do bazy public Form1() { InitializeComponent(); conn = new NpgsqlConnection("server=127.0.0.1;Port=5432;User Id=postgres;Password=haslo;Database=postgres;"); // połączenie z bazą danych conn.Open(); Szukaj(); } private void textBox1_TextChanged(object sender, EventArgs e) //funkcja obsługująca zdarzenie zmiany tekstu w TextBoxie { Szukaj(); } void Szukaj() { NpgsqlCommand command; // obiekt reprezentujący jedno zapytanie do bazy command = new NpgsqlCommand("SELECT * FROM testowa_1 WHERE tekst LIKE '%" + textBox1.Text + "%'", conn); // zapytanie sql pobierające z tabeli testowa_1 wszystkie rekordy //zawierające w dowolnym miejscu pola 'tekst' ciąg wpisany w TextBoxie NpgsqlDataReader dr = command.ExecuteReader(); listView1.Items.Clear(); int i = 0; while (dr.Read()) { listView1.Items.Add(dr[0].ToString()).SubItems.Add(dr[1].ToString()); i++; } label1.Text = i.ToString(); //label1 wyświetla liczbę znalezionych rekordów } } }
Nazwy kontrolek pozostawiłem domyślne żeby nie musieć dodatkowo wyjaśniać co dana nazwa reprezentuje.
Na zakończenie
Sposób który tutaj zaprezentowałem jest moim osobistym wymysłem i na pewno ma wadę w postaci dużej liczby zapytać wysyłanych do bazy. W przypadku gdy tylko jeden program łączy się z bazą i pobiera dane tylko z jednej tabeli wszystko działa OK, jednak na pewno sprawdzę jak sprawa będzie się miała gdy programów i tabel będzie kilka i będą się łączyć z bazą w sieci lokalnej, a nie na localhoście. Jeżeli ktoś zna lepszy sposób na rozwiązanie tytułowej kwestii to oczywiście zachęcam do podzielenia się nim w komentarzach.
Leave a Comment