Dawid Cieszyński

.NET/PHP Software Developer

Jeden z moich klientów korzysta z systemu Joomla i dodatku VirtueMart (moduł sklepu internetowego). Żeby uprościć jego obsługę pomyślałem nad napisaniem aplikacji do aktualizacji cen pobieranych z jakiegoś źródła.

Aplikacja korzysta z DB_Linq czyli Linq Provider for MySql, Oracle and PostgreSQL.  Niestety DB_Linq nie ma aktualnie żadnej dokumentacji. Za to znalazłem drobne informacje na stronie Primary Objects. Wykorzystałem wersję 0.18 która jest deprecated ponieważ z 0.19 miałem problem z wygenerowaniem klas linq.

Z wersją 0.18 też był problem…

DbMetal failed:System.ArgumentException: magma string must not be empty

Okazało się, że jest problem jeśli nazwy tabel w bazie zawierają obok siebie dwa znaki podkreślenia.

Oczywiście pogrzebałem trochę w kodzie i to sobie poprawiłem:

//\DbLinq-0.18\src\DbLinq\Language\Implementation\AbstractWords.cs, linia 139
public virtual IList<string> GetWords(string text)
{
    text = text.Replace("__", "_"); //zamienia dwa podkreślenia na jedno

Teraz mogłem już zacząć korzystać z zalet linq połączonego z bazą MySQL.

Dla tych którzy nie znają angielskiego (lub nie lubią czytać po angielsku) napiszę co po koli należy zrobić aby łatwo pogrzebać sobie w bazie MySQL.

  1. Ściągnąć DB_Linq
  2. Wygenerować klasy modelu na podstawie struktury bazy danych. Zostanie utworzony jeden plik o nazwie takiej samej jak nazwa bazy
    dbmetal /server:1.2.3.4 /user:dbuser /password:password /provider:MySql /database:people /language:C#
    
  3. To wszystko :)
    Klasy mamy gotowe więc można operować na bazie.

Odczytywanie danych z bazy (SELECT).

public ObservableCollection GetProducts()
{
    using (var connection = new MySqlConnection("server=server.pl;user id=user; password=haslo; database=baza"))
    {
        connection.Open();
        using (var dataContext = new BazaDataContext(connection))
        {
 
  var items = from s in dataContext.JoSVMProduct
                        join pc in dataContext.JoSVMProductPrice on s.ProductID equals pc.ProductID
                        orderby s.ProductName ascending
                        select new ProduktVm
                                   {
                                       ProductId = s.ProductID,
                                       ProductSku = s.ProductSku,
                                       ProductName = s.ProductName,
                                       ProductPrice = pc.ProductPrice,
                                       ProductFullImage = s.ProductFullImage,
                                   };
 
            var collection = new ObservableCollection();
            foreach (var c in items)
                collection.Add(c);
 
            return collection;
        }
    }
}

W powyższym przykładzie pobieram dane o produktach i cenach i tworzę sobie obserwowalną kolekcję. ProduktVm to moja klasa pośrednia.

Aktualizowanie danych w bazie (UPDATE).

using (var conn = new MySqlConnection("server=server.pl;user id=user; password=haslo; database=baza"))
{
    conn.Open();
    using (var context = new BazaDataContext(conn))
    {
        var items = from pc in context.JoSVMProductPrice
                    where pc.ProductID == 1
                    select pc;
        var i = items.First();
        i.ProductPrice = -1;
        context.SubmitChanges();
    }
}

Dodawanie danych do bazy (INSERT).

using (PeopleDataContext context = new PeopleDataContext(connection))
{
    // Create a LINQ to SQL class to fill the properties.
    Person person = new Person();
    person.FirstName = txtFirstName.Text;
    person.LastName = txtLastName.Text;
    person.Age = Convert.ToInt32(txtAge.Text);
 
    context.Person.InsertOnSubmit(person);
    context.SubmitChanges();
}           

W mojej aplikacji jeszcze insertów nie robię więc podaję przykład z Primary Objects

Na koniec dodam jeszcze, że VMManager miał pobierać dane z Excela, ale niestety nie znalazłem żadnego działającego sposobu pobrania danych z arkusza. Zapisałem arkusz jako plik tekstowy z danymi rozdzielonymi znakami tabulacji i takie dane to już da się odczytać.