Dynamiczne wyszukiwanie w bazie

08 sierpnia 2012 o 21:52 Autor:

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *