English version - not all articles are translated
VirtueMart Manager: VirtueMart Price Updater czyli LINQ z MySQL przy pomocy DB_Linq
- Details
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.
- Ściągnąć DB_Linq
- 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#
- 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ć.