lab_2_5_dataset

25
Laboratorijske vježbe 2.5 Pristup bazi podataka korištenjem DataSet-ova Sažetak U ovim vježbama proći ćemo kroz gotovo najstariji način korištenja baze podataka koju podržava .NET, odnosno korištenjem DataSet-ova. Uz same DataSet-ove proći ćemo kratko i kroz SQL Server 2012. Pročiti ćemo pohranjene procedure, okidače (engl. trigger) i vezanje podataka sa kontrolama (engl. data binding) Ključne riječi: ADO.NET, DataSet, SQL Server 2012 Katedra za razvoj informacijskih sustava Programsko inženjerstvo, akademska godina: 2012/13

Upload: ddomjani

Post on 12-Dec-2015

3 views

Category:

Documents


1 download

DESCRIPTION

distribucija

TRANSCRIPT

Laboratorijske vježbe 2.5 Pristup bazi podataka korištenjem DataSet-ova

Sažetak

U ovim vježbama proći ćemo kroz gotovo najstariji način korištenja baze podataka koju

podržava .NET, odnosno korištenjem DataSet-ova. Uz same DataSet-ove proći ćemo kratko i

kroz SQL Server 2012. Pročiti ćemo pohranjene procedure, okidače (engl. trigger) i vezanje

podataka sa kontrolama (engl. data binding)

Ključne riječi: ADO.NET, DataSet, SQL Server 2012

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 2

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Sadržaj

1. Uvod ....................................................................................................................................................................................... 2

2. SQL Server 2012 ................................................................................................................................................................ 2

2.1. Kreiranje baze podataka i tablica ......................................................................................................................... 3

2.2. Postavljanje upita ....................................................................................................................................................... 4

2.3. Pohranjene procedure i okidači............................................................................................................................ 4

2.4. Okidač ............................................................................................................................................................................. 5

2.5. Detach / Attach database ....................................................................................................................................... 6

2.6. Northwind baza podataka ...................................................................................................................................... 6

3. Pristupanje bazi podataka korištenjem DataSet-ova. ........................................................................................ 7

3.1. Kreiranje nove aplikacije sa pristupom podacima ........................................................................................ 8

3.2. Spajanje na bazu podataka .................................................................................................................................... 9

3.3. Prikaz podataka – READ ....................................................................................................................................... 10

3.4. Brisanje podataka - Delete .................................................................................................................................. 15

3.5. Dodavanje novih redaka – Create ..................................................................................................................... 16

3.6. Dodavanje stavki ..................................................................................................................................................... 19

3.7. Ažuriranje zapisa - Update .................................................................................................................................. 22

4. Pitanja za ponavljanje .................................................................................................................................................. 25

5. Literatura (pristupano u periodu ljetnog semestra ak.g. 2012/2013) ....................................................... 25

1. Uvod U ovim materijalima koristi ćemo sustav za upravljanje bazom podataka, kako bismo kreirali

bazu podatka i isprobali dohvaćanje, pohranu, ažuriranje i brisanje podataka (CRUD), a nakon

toga ćemo napraviti jednu aplikaciju koja samostalno pristupa podacima i omogućuje CRUD

operacije.

2. SQL Server 2012 Microsoft SQL Server je sustav za upravljanje relacijskom bazom podataka. Iako postoji više

definicija baze podataka, mi ćemo koristiti najjednostavniju prema kojoj je baza podataka

(kolokvijalno nazivana samo baza) organizirani skup podataka. Organiziran u ovom slučaju

znači da postoje stroga formalno definirana pravila koja se primjenjuju za pohranu podataka.

Sustav za upravljanje bazom podataka omogućuje kreiranje, čitanje, ažuriranje i brisanje baza

podataka, dok baza podataka sadrži tablice, koje su preslika relacijskog modela podataka i u

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 3

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 1: Kreiranje strukture tablice

njima pohranjuje strukturirane zapise. Uz Microsoft SQL Server 2012 kojeg ćemo koristiti na

ovom kolegiju, postoji još mnogo drugih, primjerice: MySQL, PostgreSQL, Oracle, Sybase,

dBase, IBM DB2 itd.

2.1. Kreiranje baze podataka i tablica

Pokrenuti ćemo SQL Server Management Studio koji će nam omogućiti pregled baza

podataka. Ovisno o instalaciji sustav nas traži lozinku i korisničko ime. Nakon uspješne

prijave, prikazuje se prozor aplikacije vrlo slične strukture kao Visual Studio.

Prema uputama u tablici 1, kreirati ćemo bazu podataka. U stablastom ispisu na Databases

ćemo pritisnuti desni klik i odabrati New Database, nakon toga navodimo ime baze podataka

i završeno je kreiranje. Bazu ćemo nazvati PIDatabase. Postoje još i napredne mogućnosti

kreiranja baze podataka, no kako to nije temelj ovog kolegija i potrebna su određena

predznanja, u ovim materijalima nećemo ići u daljnje razmatranje kreiranje baze podataka.

Tablica 1: Postupak kreiranja baze podataka, dodavanja nove tablice i otvaranja prozora za upite

Kreiranje baze podataka Dodavanje nove tablice Postavljanje upita nad bazom

Nakon uspješno kreirane baze podataka,

unutar datoteke Databases pojaviti će se i

upravo kreirana PIDatabase. Na nju ćemo

ponovno pritisnuti desni klik miša i odabrati

„New Table“. Nakon toga otvara se tablica

koja izgleda poput tablice na slici 1. Dodati

ćemo te atribute i za svakog odabrati tip

podataka iz padajućeg izbornika „Data

Type“. Polje ID će nam biti primarni ključ, to

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 4

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

ćemo postaviti tako da desnim klikom aktiviramo kontekstni izbornik i odaberemo opciju „Set

primary key“

Slika 2: Automatsko povećavanje primarnog ključa

Obzirom da je primarni ključ prirodni broj i da iza njega ne stoji poslovna logika, možemo

koristiti samo-povećavajuće polje. Da bismo to napravili u donjem prozoru sa svojstvima

proširiti ćemo opciju“Identity specification“, kao na slici 2. Polje „Is Identity“ ćemo postaviti na

Yes, polje „Identity Increment“ ćemo postaviti na 1 (vrijednost za koju se svaki puta kod

dodavanja novog zapisa u bazu, primarni ključ poveća) i polje „Identity Seed“ ćemo postaviti

na 1 (vrijednost od kojeg se primarni ključ počinje brojat).

Da bismo okončali proces kreiranja tablice, kliknuti ćemo na Save. To će nam otvoriti novi

prozor u kojem biramo naziv tablice, napisati ćemo Customer.

2.2. Postavljanje upita

Prije postavljanja upita, moramo otvoriti prozor u kojeg ćemo ih pisati. Da bismo to napravili,

na bazu podataka koju želimo koristiti pritisnemo desni klik i odaberemo opciju „New Query“,

kao na tablici 1. Sada možemo unijeti kod kojim ćemo dodati prvi zapis u bazu podataka:

Kod

insert into Customer (CompanyName, ContactName, ContactTitle, Email, Active) values ('Microsoft', 'Joe Willson', 'MR', '[email protected]', 0);

Konačno, da bismo upit izvršili, označiti ćemo upit koji želimo izvršiti i odabrati ćemo opciju

Execute. Moguće je napisati više upita, a SQL Server će izvršiti samo one označene.

2.3. Pohranjene procedure i okidači

Pohranjena procedura je blok SQL upita koji omogućuje funkcionalnost sličnu kao metoda u

objektno orijentiranom programiranju. Primjerice, niz upita koji rade zapis, validaciju, zamjenu

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 5

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

podataka itd., pohranimo kao proceduru koju možemo iznova pozivati. Narudžba i ponuda u

bazi podataka mogu biti tablice vrlo slične (često i jednake) strukture. U poslovnom procesu

klijent dobiva ponudu koju može potvrditi. U tom trenutku, da ne bismo ponovno zapisivali

podatke kao narudžbu (ukoliko se ponuda ne promjeni), možemo napraviti proceduru koja će

ponudu pretvoriti u narudžbu. Sljedeći kod prikazuje kako kreirati pohranjenu proceduru koja

aktivira klijenta u bazi podataka. Neka je svaki klijent u bazi neaktivan, sve dok ne naruči

jedan proizvod. Kada ga naruči, korisnik će pokrenuti ActivitySet proceduru (npr. u aplikaciji

odabere opciju Aktiviraj)

Kod

create procedure ActivitySet @CustomerID integer AS update Customer set Active = 1 where ID = @CustomerID; GO

Ponovno označimo kod (upit) procedure i odaberemo Execute. Kao rezultat trebali bismo

dobiti poruku Command(s) completed successfully. Time je procedura pohranjena, a da bismo

je pokrenuli moramo izvršiti sljedeći upit: execute ActivitySet 1;

Ulazi parametar je 1, jer to je primarni ključ retka koji mijenjamo. Ako pogledamo proceduru

onda se vidi da koristimo parametar @CustomerID.

2.4. Okidač

Okidač je pohranjena procedura ili upit koji poziva pohranjenu proceduru koja se automatski

izvršava kao odgovor na neki događaj u bazi podataka. Sljedeći upit prikazuje okidač koji

svaki puta nakon dodavanja klijenta u tablicu Customer automatski radi aktivaciju.

Kod

create trigger UpdateActivityTrigger on Customer after insert as declare @varijabla AS int; set @varijabla = (select id from inserted); execute dbo.ActivitySet @varijabla; print 'Uspjesno sam upisao aktivnost za ' + convert(varchar, @varijabla); go

Command(s) completed successfully.

Nakon izvršavanja upita koji kreira ovaj okidač, svaki puta kada dodamo novi redak dobiti

ćemo poruku o uspješnom zapisu u bazu podataka i poruku od okidača.

Sintaksa okidača je sljedeća:

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 6

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Kod

Trigger on an INSERT, UPDATE, or DELETE statement to a table or view (DML Trigger) CREATE TRIGGER [ schema_name . ]trigger_name ON { table | view } [ WITH <dml_trigger_option> [ ,...n ] ] { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } [ NOT FOR REPLICATION ] AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > } <dml_trigger_option> ::= [ ENCRYPTION ] [ EXECUTE AS Clause ] <method_specifier> ::= assembly_name.class_name.method_name

2.5. Detach / Attach database

Podaci baze podataka mogu se „otkačiti“ i ponovno „zakačiti“ na istu ili neku drugu instancu

SQL servera. Taj je postupak vrlo koristan zbog migracije baze podataka i tim više što korisnik

koji kasnije koristi bazu podataka u aplikaciji ne mora nužno imati instalaciju SQL Server-a.

Baza podataka koja se otkači zapisana je u .mdf formatu koji je portabilna baza podataka,

odnosno baza podataka u jednoj datoteci. Obzirom na rečeno, imamo dvije mogućnosti

korištenja baze podataka; a) pristupanje preko DBMS-a (u našem slušaju SQL Server), b)

pristupanje kao datoteci (u našem slučaju .mdf)1.

Da bismo otkačili bazu podataka (engl. detach), najprije je moramo ugasiti (Take offline), a

nakon toga pokrenemo postupak kojim se ona otkači od poslužitelja baze podataka.

Možemo to zamisliti kao sljedeće, poslužitelj baze podataka, u našem slučaju SQL Server

2012 je niz utičnica koje sadrže odgovarajući napon i frekvenciju napona, svaki uređaj spojen

na utičnicu je u ovom slučaju jedna baza podataka. Bazu podataka je u ovom slučaju, kao i

neki električni uređaj, moguće isključiti, prenijeti na drugi poslužitelj jednakih karakteristika i

ponovno uključiti. Da bismo to napravili, desnim klikom na bazu podataka u izborniku Tasks

odaberemo opciju Take offline, a nakon toga, ponovno desni klik, izbornik Tasks, opcija

Detach database. Time dobijemo dvije datoteke (.mdf – podaci i .ldf – log podaci).

2.6. Northwind baza podataka

Kako ne bismo radili posebnu bazu podataka (to je gradivo ranijih kolegija) samo za pokazne

primjere ove vježbe, koristiti ćemo pokaznu bazu podataka koja dolazi sa Visual Studijom,

Northwind database. Northwind baza podataka implementira model podataka manje

organizacije i prati proces dobavljanja, naručivanja, prodaje, praćenje klijenata, zaposlenika i

1 http://msdn.microsoft.com/en-us/library/ms190794.aspx

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 7

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

dostavljača (slika 3). Northwind također sadrži procedure i okidače. U prilogu ove vježbe

dolazi otkačena datoteka Northwind koju ćemo koristiti u Visual Studiu da bismo pokazali

proces kreiranja, prikazivanja, ažuriranja i brisanja podataka putem aplikacije.

Slika 3: Struktura Northwind baze podataka - nije u pravilnoj ERA notaciji, već u MS SQL Server notaciji

3. Pristupanje bazi podataka korištenjem DataSet-ova. DataSet je klasa koja omogućuje offline pristup bazi podataka i njeni objekti predstavljaju

memorijske reprezentacije dohvaćenih podataka iz nekog izvora podataka (ne mora biti baza

podataka iako najčešće jest). DataSet predstavlja sve podatke uključujući tablice, ograničenja i

veze između tablica.

Slika 4: DataSet2

2 http://msdn.microsoft.com/en-us/library/ms180730(v=vs.90).aspx

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 8

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 5: Glavni izbornik aplikacije

Promotrimo sliku 4. Na lijevom rubu slike nalazi se neki izvor podataka (XML datoteka ili baza

podataka), a na desnom rubu slike nalazi se korisnik koji pregledava podatke pomoću

DataGrid kontrole. Korištenjem DataSeta procedura za dobavljanje podataka je sljedeća.

Korisnik trži neke podatke za ispis na DataGrid kontrolu. DataGrid kontrola pomoću

BindingSource klase povezana je sa podacima. BindingSource ponaša se kao izvor podataka

za neku kontrolu (primjerice TextBox, ComboBox ili DataGridView). Svaku promjenu korisnika

propagira na sljedeći sloj prema bazi podataka, a svaku promjenu baze podataka propagira

dalje prema korisniku. Ukratko omogućuje „vezanje“ kontrole za podatak. Te podatke dobiva

iz DataSet kontrole koja je memorijska preslika baze podataka, a ta memorijska preslika baze

podataka puni se pomoću TableAdapter klase. Dakle korisnik zatraži podatke, BindingSource

potraži te podatke u DataSet-u, kojeg je prethodno napunilo TableAdapter. TableAdapter

sadrži upite prema kojima ima mogućnost filtrirati DataSet. Ukoliko korisnik mijenja podatke,

oni će se putem BindingSource-a mjenjati samo do DataSet-a. Tek nakon što korisnik

odabere „Save“ (ili programer tako isprogramira), podaci iz DataSet-a preslikavaju se u bazu

podataka. Više o tome na http://blogs.msdn.com/b/bethmassi/archive/2007/09/19/binding-

multiple-comboboxes-to-the-same-datasource.aspx.

3.1. Kreiranje nove aplikacije sa pristupom podacima

Kreiranje aplikacije s modalnim prozorima

Nakon što smo kreirali Windows Forms projekt, Form1 ćemo preimenovati u frmMain i urediti

svojstva:

Text ACME d.o.o.

StartPosition CenterScreen

IsMdiContainer True

Ovo zadnje svojstvo nam omogućuje kreiranje forme

koja može ugnijezditi druge forme. Na frmMain ćemo

još dodati MenuStrip kontrolu koja će biti glavni

izbornik aplikacije. Strukturu izbornika ćemo napraviti

tako da File sadrži opciju Exit, a Data sadrži opcije za

prikaz tablica iz baze podataka kao na slici. Name

svojstvo izbornika ćemo postaviti msMain, a svaki

element izbornika ćemo početi prefiksom „mi“ (kao menu item) i nastaviti sa strukturom

izbornika. Prema slici, Orders opcija će se zvati miDataBrowseOrders, opcija Browse će se

zvati miDataBrowse.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 9

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 6: Dodavanje izvora podataka

3.2. Spajanje na bazu podataka

Kao što smo najavili, za ovu vježbu koristiti

ćemo pokaznu bazu podataka Northwind koja

je u obliku Microsoft SQL Database datoteke.

Prvi korak je dodavanje izvora podataka (Data

Source). U izborniku DataSources (ukoliko nije

vidljiv, unutar izbornika View, Other Windows,

Data Sources) odaberemo Add new datasource.

Nakon pokretanja „čarobnjaka“ za

dodavanje novog izvora podataka, odabrati

ćemo bazu podataka (Database), nakon toga DataSet. Iz sljedećeg izbornika kliknuti ćemo na

gumb New Connection. Na novom prozoru ima nekoliko zanimljivih opcija. Gumbom Change

se otvara novi prozor na kojem biramo tip baze podataka na kakvu se spajamo. U ovom

prozoru možemo postaviti korisničko ime, lozinku, kreirati novu bazu podataka itd. Mi ćemo

odabrati Change… i odabrati Microsoft SQL Server Database File.

Lociranje datoteke Testiranje veze prema bazi podataka

Nakon toga će se dialog s kojeg smo krenuli promijeniti i tražiti će nas lokaciju .mdf datoteke.

Kada smo je pronašli, testirati ćemo vezu prema bazi podataka pritiskom gumba „Test

Connection“. Ako je rezultat „Test connection succeded“ tada je baza podataka spremna za

korištenje i možemo kliknuti na OK.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 10

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 8: Tablice koje ćemo koristiti

Slika 7: Želimo li presnimati datoteku baze podataka u projekt?

Nakon tog koraka otvara se prozor koji nas želimo li presnimiti bazu podataka u projekt, mi

ćemo odabrati NE.

U posljednjem koraku moramo odabrati koje ćemo

sve tablice, poglede, procedure i funkcije iz baze

podataka koristiti. Kao i na slici odaberemo

Categories, Customers, Employees, Order Details,

Orders, Products i Suppliers. Nećemo koristiti sve

tablice, već ćemo pokazati samo jedan CRUD primjer a

ostatak ostavljamo čitateljima za implementaciju.

3.3. Prikaz podataka – READ

Podatke ćemo prikazivati na prozoru kojeg ćemo aktivirati iz izbornika. Napraviti ćemo novi

direktorij u strukturi projekta i nazvati ga DataBrowseForms. Unutar tog direktorija ćemo

dodati novu formu i nazvati je frmBrowseOrders. Unutar izbornika Data, Browse, Orders

odabrati ćemo novu metodu za rukovanje događajem MouseUp i tu ćemo pokretati formu za

prikaz narudžbi:

Kod

private void miDataBrowseOrders_MouseUp(object sender, MouseEventArgs e) { DataBrowseForms.frmBrowseOrders browseOrdersFrom = new DataBrowseForms.frmBrowseOrders(); browseOrdersFrom.MdiParent = this; //<- postavlja prozor kao dijete od frmMain browseOrdersFrom.WindowState = FormWindowState.Maximized; browseOrdersFrom.Show(); }

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 11

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Ona će nam poslužiti za prikaz narudžbi i stavki narudžbi. Za to moramo napraviti sljedeće:

1. Dodati DataGridView kontrole za narudžbe (Orders) i stavke narudžbi (Order Details).

To ćemo napraviti tako da iz DataSources prozora kliknemo na tablicu i dovučemo je

na prozor. To napravimo za svaku tablicu.

2. Sada ćemo promjeniti svojstva forme (Text = Browse orders, StartPosition=

CenterParent)

3. Za DataGridView kontrole koje smo dodali promijenimo svojstvoj Anchor da dobijemo

otprilike jednaki izgled kao i na slici:

Slika 9: Pripremljene DataGridView kontrole

4. Za DataGridView kontrole svojstvo SelectionMode ćemo postaviti na FullRowSelect,

svojstvo AllowUsersToAddRows = false.

Možemo pokrenuti aplikaciju i primijetiti da se ispisuju podaci, no tablica sa narudžbama

nije povezana sa tablicom stavki. Korisnik želi takav prikaz da svaki puta kada označi neku

narudžbu, vidi njene detalje, odnosno stavke. Pogledajmo programski kod koji se nalazi

ispod ove forme:

Kod

private void ordersBindingNavigatorSaveItem_Click(object sender, EventArgs e) { this.Validate(); this.ordersBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwndDataSet); } private void frmBrowseCategories_Load(object sender, EventArgs e) { // TODO: This line of code loads data into the 'northwndDataSet.Order_Details' table. You can move, or remove it, as needed. this.order_DetailsTableAdapter.Fill(this.northwndDataSet.Order_Details); // TODO: This line of code loads data into the 'northwndDataSet.Orders' table. You can move, or remove it, as needed. this.ordersTableAdapter.Fill(this.northwndDataSet.Orders); }

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 12

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 10: Dodavanje novog upita na

TableAdapter

Prva metoda izvršava se kada korisnik u „Binding Navigator“ kontroli pritisne na ikonu za

spremanje. Pokrene se postupak validacije podataka, zatvara se BindingSource i TableAdapter

preslikava sadržaj našeg DataSet-a u bazu podataka (vidi uvodni tekst). Druga metoda,

prilikom učitavanja forme pročita podatke iz baze u tablice unutar DataSet-a. DataGridView

kontrole povezane preko BindingSource-a na northwindDataSet. Za svaki DataGridView to je

moguće vidjeti u svojstvu DataSource. Ono što želimo jest OrderDetails tablicu puniti ovisno

o odabranom primarnom ključu iz Orders tablice. Za to moramo napraviti novi upit u bazi

podataka.

5. Da bismo kreirali novi upit iz Solution Explorer

prozora odabrati ćemo northwindDataSet.xsd

pronaći tablicu Order Details i u njezin

TableAdapter kliknuti desnim gumbom miša.

Odabiremo opciju Add Query… kao na slici.

U sljedećem prozoru koji se otvori, odabrati ćemo

„Use SQL statements“, nakon toga „SELECT which

returns rows“ i zatim odaberemo Query Builder i

podesimo upit tako da vraća samo one retke od

određene narudžbe. Napravimo novu varijablu i

nazovemo je OrderID

Slika 11: Query Builder

Možemo testirati upit da vidimo dobivamo li dobre rezultate. Nakon toga, odabiremo „Next“

i promjenimo nazive metoda. Ono što se događa u pozadini jest da će Visual Studio

generirati metode na TableAdapter-u za Order Details tablicu, pa ćemo umjesto dosadašnje

metode Fill (vidi raniji kod), pozivati novu metodu (prema slici).

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 13

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 12: Odabir naziva metoda za punjenje DataTable-a

Sada tablica izgleda nešto drugačije, odnosno vidljiv nam je novi, upravo dodani upit.

Slika 13: Konačan izgled TableAdapter-a nakon dodavanja novog upita

Vraćamo se u frmBrowseOrders dizajner i dodati ćemo novu metodu za rukovanje

događajem SelectionChanged nad kontrolom ordersDataGridView, te promjeniti raniju

metodu za rukovanje događajem Load:

Kod

private void frmBrowseOrders_Load(object sender, EventArgs e) { this.ordersTableAdapter.Fill(this.northwndDataSet.Orders); } private void ordersDataGridView_SelectionChanged(object sender, EventArgs e) { if (ordersDataGridView.RowCount > 0) { int orderID = int.Parse(ordersDataGridView.CurrentRow.Cells[0].Value.ToString()); this.order_DetailsTableAdapter.FillByOrderID(this.northwndDataSet.Order_Details, orderID); } }

Ako sada pokrenemo aplikaciju i navigiramo kontrolom za prikaz narudžbi, stavke će se

mijenjati i prikazivati samo one za narudžbu koju promatramo.

Fino podešavanje prikaza DataGridView kontrole

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 14

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Kao što možete uočiti neki atributi tablice Orders i Order Details su nepotrebni ili nejasni.

Primjerice, CustomerID, EmployeeID ili RequiredDate nam ne znače mnogo isto kao iz

ProductID nismo sigurni o kojem se proizvodu radi toliko dugo dok ne znamo šifru. Najprije

ćemo neke atribute sakriti, a ProductID ćemo izmijeniti tako da prikazuje naziv, a ne šifru.

Odabrati ćemo orderDataGridView i u njenom gornjem desnom kutu kliknuti na malu ikonu

trokuta.

Slika 14: Izbornik za fino podešavanje DataGridView kontrole

Pojaviti će se izbornik kao na slici na kojem trebamo odabrati Edit Columns… Time dobivamo

detaljan prikaz svih redaka te možemo mijenjati njihov tip, naziv, prikaz itd. Za Kolone

CustomerID, EmployeeID i RequiredDate ćemo postaviti na Visible = false.

Slika 15: Uređivanje stupaca

Slično ćemo napraviti i za order_DetailsDataGridView. Umjesto da vidimo šifre, ProductID

želimo korisniku prikazati naziv proizvoda. Da bismo to omogućili za ColumnType ćemo

odabrati DataGridViewComboBoxColumn i kao na slici ćemo odabrati novi DataSource,

tablicu Products iz northwindDataSet.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 15

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 16: Uređivanje izvora podataka, podataka za prikaz i podatka za selekciju

Nakon toga imamo mogućnost napraviti razliku između toga što korisniku prikazujemo, a što

će VisualStudio u pozadini koristiti i to preko DisplayMember opcije koju ćemo postaviti na

ProductName, a ValueMember na ProductID. Time prikazujemo naziv a koristimo šifru. Da bi

tablica i dalje izgledala kao tablica (bez kolone sa ComboBox kontrolom) unutar kategorije

Apperence, za DisplayStyle ćemo odabrati Nothing i kao naziv kolone (Header text) ćemo

staviti Product.

Pokrenemo aplikaciju.

Slika 17: Aplikacija - promjenjeni izgled stupca vanjskih ključeva

Primijetite da sada kako pretražujemo elemente, više se ne prikazuje šifra, već naziv artikla i

time je završen Read.

3.4. Brisanje podataka - Delete

Ukoliko ništa ne diramo, aplikacija koju smo do sada napravili omogućiti će brisanje. Kada

smo prvi puta dodali ordersDataGridView kontrolu, VisualStudio je generirao i

BindingNavigator kontrolu sa prikazom trenutne pozicije, gumbima za pomicanje po tablici,

gumbima za spremanje, brisanje i dodavanje novih zapisa.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 16

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Možemo probati koristiti tipku brisanja. Primjetite da ukoliko ne odaberemo opciju Save,

podaci se neće obrisati. To je upravo zbog DataSet-a. Nama se ne sviđa ova generirana

metoda za brisanje, već želimo vlastitu i to takvu, da korisnika pitamo dali je siguran želi li

obrisati zapis. Za to, u dnu dizajnera odaberemo ordersBindingNavigator i postaviti svojstvo

DeleteItem postaviti na (none). Dva puta ćemo kliknuti na opciju za brisanje kako bi nam se

generirala metoda za rukovanje klikom.

Obzirom da su nam narudžbe vezane uz detalje narudžbi, odnosno stavke, ne možemo

narudžbu toliko dugo obrisati dok postoji stavaka, stoga, moramo najprije obrisati sve stavke,

a onda tek narudžbu. To možemo napraviti na nekoliko načina, no mi ćemo napisati

jednostavan kod koji će to napravit. Kliknuti ćemo na ikonu za brisanje i izmijeniti kod

metoda.

Kod

private void ordersBindingNavigatorSaveItem_Click(object sender, EventArgs e) { this.Validate(); this.order_DetailsBindingSource.EndEdit(); this.ordersBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwndDataSet); } private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e) { if (MessageBox.Show("Do you whish to delete this order?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { //delete order details for (int i = 0; i < order_DetailsDataGridView.Rows.Count; i++) { order_DetailsDataGridView.Rows.RemoveAt(i); } ordersDataGridView.Rows.RemoveAt(ordersDataGridView.CurrentRow.Index); } }

3.5. Dodavanje novih redaka – Create

Ono što sada želimo napraviti je dodavanje novih narudžbi. Za to moramo imati novu formu

koja će prihvaćati podatke i zapisivati ih u bazu. No svaka narudžba ima neke stavke, stoga

moramo napraviti i formu koja će omogućiti dodavanje stavaka. Kada korisnik dobije novi

prozor sa mogućnošću kreiranja narudžbe, postaviti ćemo gumb kojim će se narudžba

spremiti (kako bismo dobili primarni ključ iz baze podataka), proslijediti ključ putem

konstruktora forme za dodavanje stavaka i vezati nove stavke uz ključ upravo kreirane

narudžbe.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 17

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Formu za dodavanje narudžbe kreirati ćemo unutar novog foldera našeg Solution Explorera,

DataCreateForms i nazvati ju frmCreateOrder. Da bismo je prikazali, u

orderBindingNavigatoru ćemo opciju AddNewItem postaviti na (none) i dodati metodu za

rukovanje klikom.

Kod

private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { DataCreateForms.frmCreateOrder frmOrder = new DataCreateForms.frmCreateOrder(); frmOrder.ShowDialog(); //<- dialog ne dozvoljava fokus drugih kontroli }

A na novu formu, ovaj put nećemo dovlačiti tablicu iz izbornika DataSources, već element po

element. Visual Studio će nam generirati labelu i kontrole za odabrane tipove podataka, koje

su već povezane na bazu podataka (engl. Binding). Da nisu povezane, morali bismo imati kod

koji svaku vrijednost čita iz određene kontrole (npr. TextBox) i stavlja ih u upit za kreiranje

zapisa. Prije nego što počnemo dovlačiti atribute na kontrole, za CustomerID i EmployeeID za

vrstu kontrole odabrati ćemo ComboBox. Napraviti ćemo kontrolu da nam izgleda kao slika:

Slika 18: Uređivanje forme za dodavanje nove narudžbe - ComboBox zamjena

Kao što smo ranije kod DataGridView kontrole

odabirali ValueMember i DisplayMember,

ovdje ćemo napraviti slično. Klikom trokuta na

customerIDComboBox, za DataSource ćemo

odabrati Customers, za DisplayMember

CustomerName, za ValueMember CustomerID

i za SelectedValue CustomerID. SelectedValue

se u ovom slučaju odnosi na vezu prema

trenutnoj Narudžbi. Obzirom da smo za

DataSource odabrali Customers tablicu,

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 18

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

kontrolu smo razdvojili od Orders tablice, pa pomoću SelectedValue odabiremo da nam

unutar konteksta orderBindingSource SelectedValue bude ValueMember.

Visual Studio je generirao novu kontrolu BindingNavigator koju nećemo koristiti, pa je

možemo obrisati. Umjesto toga dodati ćemo tri nova gumba: „…“ (btnAddDetails) koji će nam

služiti za otvaranje stavki, „Create“ kojim ćemo napraviti narudžbu i „Clear“ pomoću kojeg

zatvaramo prozor.

Sada ćemo dodati kod za MouseUp događaje na te gumbe:

Kod (konstruktor kod frmCreateDetails)

private void btnCreate_MouseUp(object sender, MouseEventArgs e) { createNewEntry(); } private void createNewEntry() { this.Validate(); this.ordersBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwndDataSet); } private void btnAddDetails_MouseUp(object sender, MouseEventArgs e) { createNewEntry(); int OrderId = (int)northwndDataSet.Orders.Rows[0]["OrderID"]; // frmCreateDetails ćemo kreirati nešto kasnije, no ovdje prosljedimo ID frmCreateDetails frmCreateDetails = new frmCreateDetails(OrderId); if (Editing) frmCreateDetails.Editing = true; frmCreateDetails.ShowDialog(); } private void btnClear_MouseUp(object sender, MouseEventArgs e) { this.Close(); }

Također, želimo da čim se otvori ovaj prozor, korisnik već uređuje novu narudžbu, pa

moramo promjeniti metodu Load.

Kod (konstruktor kod frmCreateDetails)

public frmCreateOrder() { InitializeComponent();} private void frmCreateOrder_Load(object sender, EventArgs e) { this.employeesTableAdapter.Fill(this.northwndDataSet.Employees); this.customersTableAdapter.Fill(this.northwndDataSet.Customers); ordersBindingSource.AddNew(); }

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 19

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Sada imamo sav kod koji nam je potreban da bismo kreirali i spremili nove narudžbe. (OPREZ,

neka su polja obavezna, pa ovdje treba još finog podešavanja i interakcije s korisnikom)

3.6. Dodavanje stavki

Kreirati ćemo novu formu unutar direktorija DataCreateForms i nazvati je frmCreateDetails.

Promjeniti ćemo joj svojstvo Text (Add order details) i na sličan način kao ranije povući

tekstualna polja iz DataSources izbornika, no ovaj put ćemo povući i čitavu tablicu u obliku

DataGridView kontrole kako bismo vidjeli stavke koje smo dodali do sada. Uz to, pored

productIDTextBox kontrole ćemo dodati gumb „…“, koji će nam kasnije prikazati listu svih

proizvoda i u taj TextBox zapisati šifru odabranog proizvoda.

Slika 19: Forma za dodavanje stavki narudžbe

Kao i za dodavanje narudžbi, moramo podesiti formu tako da kad je korisnik otvori,

automatski se dodaje novi zapis, a kada klikne na „…“, otvara se forma sa proizvodima i

ona ima mogućnost vratiti ProductID i UnitPrice. Da bismo mogli vratiti šifru proizvoda i

cijenu, trebamo tablicu sa proizvodima. Idemo u direktorij DataBrowseForms i dodajemo

novu formu frmBrowseProducts. U nju ćemo iz DataSource kontrole povući tablicu

Products i napraviti sve promjene (postavke svojstva, selekcije, dodavanje novog

elementa u glavni izbornik, otvaranje forme na klik, sve kao i za frmBrowseOrders). Kako

želimo da nam ta tablica vraća vrijednosti, trebamo napraviti nova svojstva koja ćemo

čitati i gumbe koji će upravljati formom.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 20

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Slika 20: Forma za pretraživanje proizvoda koja vraća vrijednost odabira - Lookup

Otvoriti ćemo formu frmBrowseProducts i dodati ćemo svojstva; ProductID i UnitPrice te

njihove gettere i sttere. Kada korisnik klikne na dataGridView kontrolu ta će se svojstva

postaviti, a njih ćemo moći dohvatiti i zapisati vrijednosti u polja koja nedostaju. Stoga ćemo

morati obraditi događaj selekcije i još moramo iz tablice čitati vrijednosti. Da bismo to lakše

napravili moramo si unutar productsDataGridView kontrole postaviti imena.

Kao što slika prikazuje odabiremo opciju najprije ProductID pa UnitPrice i mijenjamo svojstvo

DataPropertyName u ProductIDColumn i UnitPriceColumn.

Slika 21: Imenovanje stupaca

Sada možemo napisati kod kojim postavljamo vrijednosti svojstava. Dodajemo novu metodu

za obradu događaja SelectionChanged nad kontrolom productsDataGridView.

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 21

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Kod

public int ProductID { get; set; } public float UnitPrice { get; set; } private void productsDataGridView_SelectionChanged(object sender, EventArgs e) { this.ProductID = int.Parse(productsDataGridView["ProductIDColumn", productsDataGridView.CurrentRow.Index].Value.ToString()); this.UnitPrice = float.Parse(productsDataGridView["UnitPriceColumn", productsDataGridView.CurrentRow.Index].Value.ToString()); }

Na gumb OK ćemo zatvarati formu (kasnije se to može izmjeniti po potrebi).

* * *

Sada se možemo vratiti na frmCreateDetails i možemo obraditi MouseUp događaj za gumb

„…“.

Kod

private void btnListProducts_Click(object sender, EventArgs e) { DataBrowseForms.frmBrowseProducts frmProducts = new DataBrowseForms.frmBrowseProducts(); frmProducts.ShowDialog(); productIDTextBox.Text = frmProducts.ProductID.ToString(); unitPriceTextBox.Text = frmProducts.UnitPrice.ToString(); }

Pomoću tog koda dohvatili smo vrijednosti i zapisali ih unutar productIDTextbox kontrole i

unitPriceTextBox kontrole koje su već vezane za bazu podataka. Time je postupak dodavanja

stavki skoro završen, no ono što još moramo napraviti jest prosljeđivanje šifre narudžbe na

koju vežemo stavke, stoga promjenimo konstruktor (čime i raniji kod na frmCreateOrder za

btnAddDetails_MouseUp):.

Kod (konstruktor kod frmCreateDetails)

public int OrderId { get; set; } public frmCreateDetails(int orderId) { InitializeComponent(); this.OrderId = orderId; }

Također ćemo izmijeniti kod za spremanje i dodavanje elementa. Najprije za

order_DetailsBindingNavigator treba promjeniti svojstvo AddNewItem na none. A nakon toga

ćemo dodati metodu koja obrađuje događaj klik za bindingNavigatorAddNewItem i za

order_DetailsBindingNavigatorSaveItem. Kod će izgledati ovako:

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 22

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Kod

private void frmCreateDetails_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.northwndDataSet.Products); this.order_DetailsTableAdapter.FillByOrderID(this.northwndDataSet.Order_Details, OrderId); // moramo napraviti filtriranje za samo one stavke koje dodajemo } private void order_DetailsBindingNavigatorSaveItem_Click(object sender, EventArgs e) { SaveCurrent(); } private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { addNewEntry(); } private void addNewEntry() { try { this.order_DetailsBindingSource.AddNew(); orderIDTextBox.Text = OrderId.ToString(); } catch (Exception ex) { MessageBox.Show("Exception: " + ex.Message); } } private void SaveCurrent() { this.Validate(); this.order_DetailsBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwndDataSet); }

Time smo završili kod za dodavanje zapisa u tablicu Order i OrderDetails.

3.7. Ažuriranje zapisa - Update

Da bismo omogućili ažuriranje trebamo napraviti minimalne promjene na postojećim

formama. Naime, kako koristimo kontrole koji su vezani za podatke (engl. data bound

controls) puno nam je lakše napraviti ažuriranje jer podatke koje prikazujemo možemo

mjenjati i spremati. Ono što nam preostaje je eliminirati automatsko dodavanje redaka

prilikom otvaranja prozora za dodavanje novih redaka. Iste ćemo koristiti i za ažuriranje.

Stoga, najprije ćemo promjeniti formu za narudžbe, odnosno frmCreateOrder.

Kod

private bool Editing { get; set; }

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 23

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

public int OrderID { get; set; } public frmCreateOrder() { InitializeComponent(); OrderID = -10; //<- mora biti postavljena pa koristimo neutralnu vrijednost -10 } // preopterećenje konstruktora (ovaj ćemo konstruktor koristiti kada korisnik odabere ažuriranje public frmCreateOrder(int OrderID) { InitializeComponent(); this.OrderID = OrderID; this.Editing = true; } private void frmCreateOrder_Load(object sender, EventArgs e) { this.employeesTableAdapter.Fill(this.northwndDataSet.Employees); this.customersTableAdapter.Fill(this.northwndDataSet.Customers); if (this.OrderID != -10) { this.ordersTableAdapter.FillByOrderID(this.northwndDataSet.Orders, this.OrderID); // ako je ažuriranje popuni prema ID-u } else { ordersBindingSource.AddNew(); // ako nije ažuriranje } }

Sada znamo koju narudžbu uređujemo i znamo da je uređujemo pa te iste podatke možemo

proslijediti i formi za dodavanje stavki:

Kod

private void btnAddDetails_MouseUp(object sender, MouseEventArgs e) { createNewEntry(); int OrderId = (int)northwndDataSet.Orders.Rows[0]["OrderID"]; frmCreateDetails frmCreateDetails = new frmCreateDetails(OrderId); if (Editing) frmCreateDetails.Editing = true; frmCreateDetails.ShowDialog(); }

A u formi za dodavanje stavki samo moramo osigurati da se ne dodaje novi redak čim se

forma otvori, pa ćemo i njezin kod izmjeniti:

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 24

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

Kod

public int OrderId { get; set; } public bool Editing { get; set; } public frmCreateDetails(int orderId) { InitializeComponent(); this.OrderId = orderId; Editing = false; } private void frmCreateDetails_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.northwndDataSet.Products); this.order_DetailsTableAdapter.FillByOrderID(this.northwndDataSet.Order_Details, OrderId);

if (!Editing) { addNewEntry(); }

}

I sada možemo dodati kontekstni izbornik, koji će se pojaviti kada unutar tablice

frmBrowseOrders kliknemo desni gumb miša, a sadržava opciju ažuriranja. Za to, iz izbornika

sa kontrolama dodajemo novi ContextStripMenu i nazovemo ga ordersContextStripMenu.

Unutar njega slično kao i za glavni izbornik dodajemo novu opciju Edit i na nju metodu za

rukovanje događajem MouseUp. Prije toga, moramo obraditi klik desnog gumba miša na

ordersDataGridView kontrolu koja će prikazati izbornik i označiti redak (jer tako možemo

dohvatiti šifru). Moramo simulirati klik miša i označavanje redka. Konačan kod izgleda:

Kod

private void ordersDataGridView_MouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { DataGridView.HitTestInfo hitTest = ordersDataGridView.HitTest(e.X, e.Y); ordersDataGridView.ClearSelection(); ordersDataGridView.Rows[hitTest.RowIndex].Selected = true; ordersContextStripMenu.Show(ordersDataGridView,e.Location); } } private void editToolStripMenuItem_MouseUp(object sender, MouseEventArgs e) { int OrderID = int.Parse(ordersDataGridView.SelectedRows[0].Cells["OrderIDColumn"].Value.ToString()); DataCreateForms.frmCreateOrder order = new DataCreateForms.frmCreateOrder(OrderID); order.ShowDialog(); }

© 2013, University of Zagreb, Faculty of Organization and Informatics, Varaždin 25

Katedra za razvoj informacijskih sustava

Programsko inženjerstvo, akademska godina: 2012/13

4. Pitanja za ponavljanje

1. Što je DataSet?

2. Što je okidač (trigger) u bazi podataka?

3. Navedite primjer okidača (triggera) i scenarij korištenja.

4. Što je pohranjena procedura?

5. Dali se podaci u DataSetu automatski ažuriraju u bazi podataka?

6. Što je TableAdapter?

7. Što je Identity polje?

8. Čemu služi attach/detach baze podataka?

9. Što je MDI container?

10. Što je data binding?

5. Literatura (pristupano u periodu ljetnog semestra ak.g.

2012/2013) 1. http://msdn.microsoft.com/en-us/library/ss7fbaez.aspx

2. http://msdn.microsoft.com/en-us/library/h43ks021.aspx

3. http://msdn.microsoft.com/en-us/library/ms189799.aspx