LINQ TO SQL w dużym skrócie jest to zintegrowany język zapytao pozwalający na mapowanie relacyjnych baz danych na model obiektowy. Zanim ktokolwiek postanowi użyd tego w swoim projekcie, należy zaznaczyd że można skorzystad z tego wyłącznie do baz firmy MS. Pozostałe bazy danych, będzie można obsłużyd za pomocą dblinq. Jest to narzędzie zewnętrzne dostępne na stronie: http://code.google.com/p/dblinq2007/downloads/list Na dzieo dzisiejszy DBLinq osiągnęło wersje 0.17 a komentarze i opisywane problemy raczej nie zachęcają do stosowania w większych projektach. Docelowo ma ono obsługiwad bazy PostgreSQL, MySQL oraz Oracle. Jeżeli już zdecydowaliśmy się na jedyny słuszny wybór producenta, zastanówmy się której z baz powinniśmy użyd. Możliwości mamy trzy: MsSQLServer w wersji Express lub pełnej, Baza danych MS Access, MsSQLServerCE Najbardziej interesującą opcją, z punktu widzenia programisty aplikacji desktopowych, jest oczywiście możliwośd dołączenia całej bazy najlepiej w formie jednego pliku do aplikacji. Wybór trzeciej opcji, pozwoli na realizacje powyższego wymagania. MsSQL Server CE wady Przede wszystkim wydajnośd samej bazy, która chyba jest pozbawiona jakichkolwiek optymalizacji. Wprowadzenie modyfikacji, lub przeszukiwanie, trwa zdecydowanie dłużej niż w bazach PostgreSQL, czy nawet MySQL Lite. Przekroczenie 2MB danych powoduje znaczny spadek wydajności. Rozwiązaniem może byd rozbicie bazy np. na cztery mniejsze bazy. Wykonanie mapowania wymaga wykorzystania narzędzia konsolowego. Ograniczenie 8KB na wiersz. Duża wada w przypadku serializowanych obiektów. Możliwośd obejścia poprzez dzieleniu obiektu na kilka pod elementów. Kurs LINQ TO SQL rozpocznijmy od stworzenia nowego projektu aplikacji konsolowej. Całośd projektu który pozwoli zapoznad się z opisywanymi rzeczami znajdzie się pod adresem http://czortcode.googlecode.com/files/linqkurs.zip Po stworzeniu nowego projektu musimy utworzyd nowy plik bazy danych. Z dostępnych opcji należy wybrad LocalDatabase i nadad nazwę np. BazaDanych.sdf.
Po utworzeniu bazy Visual będzie chciał tworzyd plik DataSet, klikamy cancel lub usuwamy po wygenerowaniu. Zaprezentowane za chwilę rozwiązania nie są idealnym rozwiązaniem projektowym, mają jedynie pokazad pewne funkcjonalności LINQ. Zacznijmy od stworzenia tabeli w bazie BazaDanych.sdf. Będziemy chcieli przechowywad w niej prosty obiekt osoba: Id Imie Nazwisko Klikamy dwa razy na plik bazy, powinno otworzyd się okno jak poniżej. Klikamy prawym na Tables i wybieramy CreateTable Tworzymy tabele, z automatyczną inkrementacją wartości klucza głównego:
Za autoinkrementację odpowiada pole identity ustawione na True. Kolejna ciekawostką jest wartośd Allows Nulls. Znaczenia chyba nie trzeba tłumaczyd, wynika natomiast z tego pewna niedogodnośd. Nie ma niejawnego rzutowania pomiędzy string a string? Wartośd typu string? różni się tym od normalnego tekstu, tym że może przyjąd wartośd null. Jeżeli stosuje się wartości typu nullable, doradzałbym stosowad je konsekwentnie. Sprawdzanie, konwersja itd. jest kłopotliwe. Po zatwierdzeniu tabeli, powinniśmy móc zobaczyd ją w serwer explorerze. Klikamy na tabeli osoba prawym i wybieramy opcje Show Table Data. Oczywiście nie ma w niej danych, ale w tym miejscu można je uzupełnid. Po dodaniu kilku wierszy, przechodzimy do obsługi bazy z poziomu kodu. Potrzebujemy przede wszystkim pliku mapowao bazy. Ma on rozszerzenie dbml i jest on tworzony przez narzędzie SQLMETAL. Aby móc się nim posługiwad musimy dodad odpowiednią ścieżkę, do zmiennej PATH w systemie. U mnie znajduje się ono w katalogu C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\ SQLMETAL używany jest z konsoli, jako pierwszy parametr podajemy nazwę bazy (w naszym przypadku BazaDanych.sdf), oraz nazwę generowanego pliku, w którym znajdą się mapowania (w
przykładzie drugi parametr to /dbml:plikmapowan.dbml). Po potwierdzeniu powinniśmy zobaczyd teks jak poniżej. Plik został wygenerowany, kolejnym krokiem jest dołączenie do projektu. W tym celu należy kliknąd prawym na projekcie i dodad Existing Item (trzeba dodatkowo wybrad opcję aby pokazywał wszystkie typy plików). Po otworzeniu go powinniśmy zobaczyd: Ostatnią rzeczą jaką należy wykonad jest napisanie kodu do obsługi. //Tworzymy obiekt typu osoba (klasa wygenerowana przez sqlmetal), id generowane automatycznie Osoba nowaosoba = new Osoba Imie = "Zbyszko", Nazwisko = "zbogdańca" ; //Nawiązujemy połączenie z bazą (nazwa klasy jest taka sama jak nazwa pliku bazy) BazaDanych polaczeniezbaza = new BazaDanych("BazaDanych.sdf"); //wstawienie obiektu do bazy polaczeniezbaza.osoba.insertonsubmit(nowaosoba); polaczeniezbaza.submitchanges();//zatwierdzenie zmian Linq daje ogromne możliwości ze względu na swoją elastycznośd. Poniżej przedstawiam kilka sposobów na pobranie informacji z bazy danych. //1 sposób Console.WriteLine(polaczenieZBaza.Osoba.Where( i => i.imie.contains("zbysz")).first().imie); //2 sposób Func<Osoba, bool> warosoba = (tmposoba) => (tmposoba.imie.contains("zbysz")); List<Osoba> listaos = polaczeniezbaza.osoba.where(warosoba).tolist(); listaos.foreach(delegate(osoba tmp) Console.WriteLine(tmp.Imie); ); //3 sposób var varosoby = from os in polaczeniezbaza.osoba select os;
Console.WriteLine(varOsoby.First().Imie); Console.ReadKey(); Często pojawia się koniecznośd rozszerzenia tak przygotowanych klas dodając np. dodatkowy konstruktor. Przyjrzyjmy się uważnie wygenerowanemu plikowi PlikMapowan.dbml. Składa się on z dwóch części: PlikMapowan.dbml.layout oraz PlikMapowan.designer.cs, gdy w designerze klikniemy na wygenerowanej klasie i wybierzemy opcje View Code zostanie utworzony trzeci plik PlikMapowan.cs. W nim będziemy mogli rozszerzad i modyfikowad klasy. Jest to możliwe dzięki oznaczeniu wszystkich wygenerowanych klas jako partial. W PlikMapowan.cs, znajduje się szkielet klasy: namespace LinqKurs partial class Osoba Możemy uzupełnid go o metodę ToString która mogłaby się przydad w obiekcie. partial class Osoba public override string ToString() return Imie + "----" + Nazwisko;