Master/Detail Relacija u DataSet – hijearhijski zapis u bazu podataka (Visual Studio 2008)


UVOD

Jedan od najznačajnijih fenomena u relacijskim bazama podataka je uzajamna zavisnost tabela na principu Master/Detail. Klijent aplikacije koje koriste ovu značajku implementiraju je na različite načine. Izlaskom Visual Studio 2005 Microsoft je ponudio efikasnu manipulaciju sa bazama podataka sa DataSet klasama. Postoji nekoliko limitirajućih faktora s kojim se susreću programeri razvijajući aplikacije ovom tehnologijom, a to su:

  1. Potrebna je posebna implementacija zapisa podataka iz DataSet-a u bazu podataka, u slučaju da se radi o Master/Detail relaciju izmedju tabela.
  2. Potrebna je posebna implementacija transakcijskih zapisa podataka iz više tabela.

Ova dva limitirajuća faktora, otklonjena su novom verzijom Visual Studia 2008, i to dodatnom klasom TableAdapterManager koju generiše Visual Studio prilikom importovanja više od jedne tabele u DataSet. To prosto znači da ova klasa nije dio .NET Frameworka, nego je čista nadogradnja dizajnera u Visual Studiu.

U narednom tekstu kroz primjer upoznat ćemo se sa novim proširenjem u Visula Studio 2008, te implementirati hijearhijski zapis relacijskih tabela iz DataSet-a u bazu podataka. Takodjer, ovom implementacijom ostvaren je transakcijski zapis podataka, što znači da ako zapis ne prođe u najmanje jednoj tabeli, cijeli zapis se vraća na prvobitno stanje odnosno transakcija poziva svoji članicu Roolback koja vraća stanje na prvobitno.

Klasa TableAdapterManager

clip_image002_2

Visual Studio pored generiranja klasa DataSet i korespodentnih klasa DataAdaptera za svaku importovanu tabelu, generira jos jednu klasu koja upravlja transakcijama svih tabela u DataSetu. Ovo znači da ako želimo pohraniti podatke iz klijent aplikacije u bazu podataka u kojoj je implementrana Master/Detail arhitektura, ova klasa putem članice UpdateAll() hiearhijski pohranjuje podatke.

Ova klasa posjeduje nekoliko članica pomoću kojih se ostvaruje ovaj mehanizam.

  1. UpdateAll – članica čijim pozivom ostvarujemo hijearhijsko pohranjivanje podataka
  2. UpdateDeletedRow, UpdateInsertedRow, UpdateUpdatedRow – pomoćne članice koje parcijalno pohranjuju podatke u bazu.
  3. UpdateOrder – enumeracija koja mijenja poredak izvršavanja pohranjivanja u bazu podataka. Posjeduje dva člana : InsertUpdateDelete i UpdateInsertDelete.
  4. BackupDataSetBeforeUpdate – osobina kojom obezbjedjujemo da izvršimo sigurnosnu kopiju podataka prije pohranjivanja u bazu. Ovo je osobina koja nam obezbjedjuje da u slučaju neuspjeha podatke u DataSetu vratimo na početak i eventualno ispravilo kolizije koje onemogućuju siguran zapis u bazu podataka.
Primjer TransactionDataSet
  1. Pokrenuti VS 2008 beta 2. Ako ne posjedujete ovu verziju možete je skinuti odavde.
  2. Formirajte novi projekat C# Windows Application
  3. Iz solution explorera dodajte novu stavku (DataSet komponentu) u novo formirani projekat.
  4. Povezite se sa SQLExpress serverom te napravite konekciju sa NorthWind bazom podataka. Ako ne posjedujete NorthWind bazu podataka možete je skinuti odavde.

Importujte Tabele Customers, Orders, OrderDetails, kako je prikazano nadonjoj slici.

clip_image004_2

Duplim klikom na relacije koje povezuju tabele Customers-Orders i Orders–OrdersDetail, pokazuje se dijaloški okvir za postavljanje relacija između tabela. Postavite relacije za oba slučaja kao što to pokazuje naredna slika.

clip_image006_2

Nakon podešavanja klase DataSet, otvorimo datoteku Form1.cs, i iz DataSource usidrenog prozora odvucimo prvo tabelu Customers, pa Orders i na kraju OrderDetail, kao na slici:

clip_image008_2

Otvorite datoteku izvornog koda ove forme te poredajte Fill metode kao što je to prikazano na sljedećoj slici. Napomena poredak punjenja tabela u hijearhiji je vrlo važna jer bi inače aplikacija izbacila izuzetak.

clip_image010_2

Takodjer modifikujte dogadjaj SaveItem_Click kaona slici.

clip_image012_2

Nakon ove implementacije hijearhijski zapis u bazu podataka iz DataSet klase je potpuno obezbjedjen, kao i transakcije.

U VS 2005, ovakva implementacije nije jednostava, i zahtjeva dodatnu implementaciju metoda i klasa. U jednom od narednih postova biće prikazana implementacija Transakcija u VS 2005 korištenjem DataAdaptera i DataSet klasa.

Izvorni kod za ovaj primjer možete skinuti odavde.

Advertisement

LINQ – V DIO LINQ TO SQL


Uvod u LINQ TO SQL

U prethodnim člancima upoznali smo se sa osnovnim pojmovima koji predstavljaju LINQ. U ovom dijelu upoznat ćemo se sa primjenom LINQ na MS SQL. Primjena LINQ za SQL Microsoft je razvio posebnu tehnologiju koju je nazvao LINQ TO SQL. Naredni primjer prikazuje povezivanje baze podataka MS SQL servera sa klientskom aplikacijom. Pokrenimo Visual Studio 2008 Beta 2. Ukoliko ne posjedujete ovu verziju možete je skinuti sa microsoftove stranice http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx.

Iz menija File izaberite New, a iz podmenija odaberite Project.

lintosql1

Aktiviranjem ove opcije na ekranu se pojavljuje dijalog New Project. Iz desne liste stavki izaberite Windows Forms Application. U donjem dijelu dijaloga u polje edit kontrole unesite PrviLINQtoSQLProjekt, te kliknite na dugme OK.

lintosql2

Kada VS IDE završi kreiranje projekta, iz Solution Explorera kliknite desnom tipkom miša na Naziv projekta (kao na slici) te izaberite Add New Item kao na donjoj slici.

lintosql3

Add New Item dijalog se pojavljuje na ekranu, te iz liste stavki izaberite LINQ to SQL Classes, a u edit kontrolu u donjem dijelu unesite NorthWindKlase, kako je prikazano na sljedećoj slici.

lintosql4

Nakon klika na dugme Add, u VS IDE se pojavljuje Dizajner za import stavki iz baze podataka, kao na sljedećoj slici.

lintosql5

U Server Exploreru napravite konekciju na SQLEXPRESS te odaberite NorthWind bazu podataka. Ako ne posjedujete NorthWind bazu podataka možete je skinuti odavde. Poslije uspostavljanja konekcije proširite stavku Tables, te kao na slici, te povucite i spustite tabelu Orders. U dizajneru će se pojaviti dijagram klase, kao na narednoj slici.

lintosql6

Kada smo importovati tabelu Orders, proširite stavku Stored Procedures, te povucite i spustite u drugi dio dizajnera, stornu proceduru CustOrdersDetail, kao što prikazuje donja slika.

lintosql7

Nakon importa storne procedure, povucite i spustite tabelu Order_Detail, nakon čega će dizajner izgledati kao na narednoj slici.

lintosql8

Možemo primjetiti da je dizajner pored tabele Order_Detail formirao i relaciju između tabela, kao što je to definisano u samoj bazi podataka. Kada smo formirali klase koje predstavljaju tabele i funkcije baze podataka, potrebno je sada da izvučemo podatke iz baze podataka. To ćemo učiniti tako što će mo preko DataGridView kontrole prikazati podatke iz baze podataka. Prije toga ćemo iz menija Data aktivirati opciju Show Data Sources, te će nam se pojaviti usidreni prozor DataSource, kao na narednoj slici. Aktiviranjem hiperlinka u istom prozoru pojaviće nam se čarobnjak za importovanje tabela u Data Source prozor,preko kojeg ćemo povezati DataGridView kontrolu sa bazom podataka.

lintosql9

Odaberimo stavku Object, kao na narednoj slici, te kliknimo na dugme Next.

lintosql10

U sljedećem prozoru, potražimo klasu Order, odaberimo je te kliknimo na dugme Finish. Ovaj korak je slikovno prikazan na narednoj slici.

lintosql11

Otvorimo iz Solution Explorera Form1 stavku. Sada naš DataSource prozor izgleda ka na sljedećoj slici. Povucimo i spustimo Order klasu iz datasource prozora u formu. Dizajner nam generira DataGridView kontrolu, te navigator kontrolu, kao na sljedećoj slici.

lintosql12

Klikni mo na DataGridView kontrolu desnom tipkom te odaberimo Properties opciju iz kontekstnog menija. U Properties prozoru odaberimo osobinu Dock, te podesimo je na Fill. Nakon ovih akcija koje smo uradili, ostaje nam još samo da napišemo tri linije koda, i naša aplikacije je povezana sa bazom podataka i spremna da prikaže podatke. Implementirajmo događaj FormLoad, te otvorimo Form1.cs datoteku. Definišimo član dbContest, klase NorthWindDataContext u klasi Form1. U metodi koja predstavlja događaj FormLoad, napišimo LINQ kao na sljedećoj slici. Pridružimo DataSource članu od BindingSource LINQ query, kao na narednoj slici.

lintosql13

Kompajlirajte i pokrenite aplikaciju.

Aplikacija treba da izgleda kao na narednoj slici.

lintosql14

U ovom jednostavnom primjeru vidjeli smo kako povezati klijentsku aplikaciju sa bazom podataka u samo tri linije koda, dok smo ostale akcije realizirali pomoću moćnih dizajnera VS IDE.

LINQ – .NET Language Integrated Query IV Dio


Sintaksa upita u LINQ

U prethodnim postovima vidjeli smo načine kako možemo formirati upit nad izvorom podataka. Takodjer se može primjetiti da svaki upit možemo formirati na dva, u suštini ista, a sintaktički različita načina. Naime svaki LINQ upit formiran Lambda izrazom možemo formirati tačka notacijom (Dot Notaton). Ovakav fleksibilam pristup definisanju upita u LINQ rezultat su proširenja koja se pojavljuju u novoj verziji C#, a koje smo spominjali u prethodnim postovima. Npr. definišimo LINQ upit tačka notacijom. Imamo:

var izraz= nazivi
.Where(s=>s.Lenght==6)
.OrderBy(s=>s)
.Select(s=>s.ToUpper());

Prethodni upit možemo formirati Lambda izrazom na sljedeći način:

var izraz= from s in imena
where s.Lenght ==6
orderby s
select s.ToUpper();

Na kraju ovog dijela pobrojat ćemo sve operatore koji se mogu pojaviti u LINQ upitima:

OPERATOR Opis
Where Restriktivni operator.
Select / SelectMany Operator projekcije.
Take/SkipTakeWhile/SkipWhile Parcijalni operator baziran na poziciji ili uslovnoj funkciji.
Join/GroupJoin Operator spajanja u odnosu na zadani uslov.
Concat Operator spajanja.
OrderBy/ThenBy/OrderByDescendingThenByDescending Sortiranje u uzlaznom, silaznom smijeru u odnosu na zadani uslov.
Reverse Operator sortiranja sekvence u suprotnom smijeru
GroupBy Operator grupiranja u odnosu na zadani uslov.
Distinct Operator uklanjanja duplikata elemenata u skupu.
Union/Intersect Operator koji vraća uniju ili podskup zadanih skupova elemenata.
Except Operator koji vraća komplement zadanog skupa.
ToSequence Operator konverzije u IEnumerable<T>
ToArray/ToList Operator konverzije u List<T>
ToDictionary/ToLookup Operator konverzije u Dictionary<K,T> ili LookUp<K,T> u odnosu na zadani ključ.
OfType/Cast Operator konverzije u IEnumerable<T> u odnosu na filtrirane elemente ili konverzije u tip argumenta.
EqualAll Operator jednakosti koji vraća jedanake uparene elemente.
First/FirstOrDefault/Last/LastOrDefault/Single/SingleOrDefault Operator vraćanja početne/zadnje/jednog elementa u odnosu na zadanu funkciju.
ElementAt/ElementAtOrDefault Operator vraćanja elementa određene pozicije.
DefaultIfEmpty Operator zamjene prazne vrijednosti sa podrazumijevanom.
Range Generatorski operator vraćanja broja u opsegu.
Repeat Generatorski operator vraćanja višestrukih pojavljivanja elementa zadane vrijednosti.
Empty Generatorski operator vraćanja prazne sekvence.
Any/All Kvantifikator provjere egzistencije ili univerzalnosti funkcije izraza.
Contains Kvantifikator provjere postojanja datog elementa.
Count/LongCount Agregacijski operatori brojanja elemenata.
Sum/Max/Min/Average Agregacijski oparatori kao opcione funkcije selektora.
Aggregate Agregacijski oparator, vidi dio III

Cjelokupan text u 5 dijelova koji je napisan o LINQ mozete skinuti odavde.

Source Code .NET Framework 3.5


Kako prenosi Somasegar u svom blogu, buduća verzija Visual Studio 2008 imaće mogućnost debaguranja i prolaska kroz source code .NET Frameworka 3.5. Naime, prilikom debagirnja aplikacije koju razvijamo te postavljanjem tačke prekida u source kodu, nailaskom na metode koje su implementirane u  .NET Frameworku, VS IDE 2008 će se povezivati sa microsoftvim serverom te prikazivati source kod dotične metode. Ovo je rezultat zahtjeva korisnika širom svijeta koji su radi lakšeg razvoja aplikacija zahtjevali uvid u debugiranje kroz .NET Framework. Više informacija i primjer kako pristupiti source kodu .NET Frameworka možete pogledati ovdje. Također možete pogledati i screencast o ovoj temi na channel9.com Ovo takodjer predstavlja korak dalje u otvaranju Microsoftove platforme opensource zajednici.