Tietokannat - Pääteohjaus 9
Yhdistetään wpf-sovellukseen tietokanta.
- Luo uusi Windows WPF -Projekti. Sijoita projektisi muualle kuin U:-asemalle.
- Lisää projektiisi tietokantayhteys Tools|Connect to Database.
- Valitse tietolähteeksi Microsoft SQL Server Database File.
- Sijoita tietokanta c:\mytemp\ohjaus9.mdf-tiedostoon. Anna Visual Studion luoda uusi kanta.
- Uusi tietokantayhteys ilmestyy Server Explorerin (Visual Studion vasen laita) Data Connections -listaukseen. Server Explorerissa voisit halutessasi muokata tietokannan rakennetta. Valitse tietokantayhteytesi kontekstivalikosta New Query.
- Add Table -dialogista ei tarvitse valita muuta kuin suoraan Close.
- Luo uusi tietokanta SQL-lauseilla, jotka liität valmiina olevien (SELECT FROM)päälle. SQL-lauseet saat suoritettua valinnalla Query Designer|Execute SQL.
- Älä välitä DROP TABLE -lauseisiin liittyvästä virheilmoituksesta vaan valitse Continue
- Saat pitkän virheilmoituslistauksen. Tämä johtuu DROP TABLE -lauseista, jotka yrittävät poistaa olemattomia tauluja.
- Suorita SQL-lauseet uudelleen niin et saa enää virheitä vaan tiedon lisättyjen rivien määrästä.
- Seuraavaksi voit lisätä varsinaisen uuden tietolähteen valinnalla Data|Add New Data Source. Jos tätä valintaa ei löydy niin varmista, että sinulla on MainWindow.xaml aktiivisena.
- Valitse Database ja sen jälkeen Entity Data Model. Valitse Generate from Database Valitse tietokantayhteydeksi edellä luomasi tietokantayhteys eli ohjaus9.mdf.
- Anna Visual Studion kopioida tietokanta projektisi kansioon. Huomaathan, että tietokannan sisältö palaa nyt jokaisen käynnistyskerran jälkeen alkuperäiseksi. Jos projektisi on verkkolevyasemalla et voi antaa kopioida tietokantaa. Jos haluat myöhemmin vaikuttaa kopioidaanko tietokanta vai ei niin voit säätää tätä valitsemalla Solution Explorerista tietokantasi ja muokkaamalla tietokannan Copy to Output Directory-ominaisuutta. Aiheesta tarkemmin: Debugging with Local Database File ja Local Data Overview
- Anna connectionstringin tallentua projektiisi
- Valitse tietokannasta kaikki taulut
- Voit silmäillä tietokannan rakennetta Model1.edmx-näkymästä. Aktivoi taas MainWndow.xaml
- Nyt Data Sources -välilehdeltä löytyvät kaikki tietokantasi taulut. Välilehden saat näkyviin valinnalla Data|Show Data Sources
- Voit valita kullekin taululle oletusesitystavan alasvetovalikosta. Valkkaa reseptille details-muoto.
- Voit muokata myös yksittäisten kenttien esitystapaa ja tarvittaessa piilottaa jotain turhia kenttiä näkyvistä. Piilota ReseptiID.
- Muokkaa RuokalajiID-kentän esitystavaksi Combobox. Raahaa resepti MainWindow-ikkunaan. Kokeile ikkunan toimintaa
- RuokaLajiID-kenttä ei vielä toimi kunnolla. Tämä saadaan korjattua, kun raahaat tietolähteistä hierarkisen listauksen ylimmältä tasolta Ruokalaji-taulun aiemmin ikkunaan muodostuneen RuokalajiID-Comboboxin päälle. Tämä muuttaa RuokalajiID-comboboxin asetukset paremmin toimiviksi. Tutki mitä muutoksia xamlissa tapahtuu. Aiheesta tarkemmin: How to: Create Lookup Tables in WPF Applications.
- Raahaa lomakkeelle myös Ohje mutta varmista, että raahaat sen hierarkisesta listauksesta Reseptin sisäpuolelta. Tällä varmistat, että ohje-listauksen sisältö on lomakkeella automaattisesti synkronoitu reseptiin.
- Tutki millaista koodia Visual Studio generoi MainWindow.xaml.cs-tiedostoon.
-
Lisää lomakkeelle painikkeet joilla voi siirtyä seuraavaan ja edelliseen reseptiin. Siirrä ensimmäisenä
Window_loaded-tapahtumassa luodut objektit luokan attribuuteiksi niin voit käyttää niitä kaikissa metodeissa.
Lisää sitten painikkeet ja niihin ohjelmakoodi:
// edellinen if (reseptiViewSource.View.CurrentPosition > 0 ) reseptiViewSource.View.MoveCurrentToPrevious(); // seuraava if (reseptiViewSource.View.CurrentPosition < ((CollectionView)reseptiViewSource.View).Count - 1) reseptiViewSource.View.MoveCurrentToNext();
- Lisää painike jolla voit kokeilla uuden Reseptin syöttämistä seuraavanlaisella koodilla:
Resepti uusiresepti = new Resepti // seuraavat tiedot pitäisi tietysti kysyä erillisellä lomakkeella { Nimi = "Hernekeitto", Henkilomaara = 4, Kuvaus = "perusherkku", RuokalajiID = 1 // tämä pitää keksiä jostakin, pitäisi olla erillinen listbox tms josta valitaan }; // voidaan lisätä liittyvät objektit suoraan oliomallin kautta Ohje uusiohje = new Ohje(); uusiohje.Vaihenro = 1; uusiohje.Ohjeteksti = "sotke kaikki kattilaan"; uusiresepti.Ohje.Add(uusiohje); Ohje uusiohje2 = new Ohje(); uusiohje2.Vaihenro = 2; uusiohje2.Ohjeteksti = "Lämmitä"; uusiresepti.Ohje.Add(uusiohje2); // vasta seuraavat rivit lisäävät tiedot tietokantaan ohjaus9Entities.Resepti.AddObject(uusiresepti); ohjaus9Entities.SaveChanges(); // päivittää gridin ajantasalle reseptiViewSource.Source = reseptiQuery.Execute(System.Data.Objects.MergeOption.AppendOnly); reseptiViewSource.View.MoveCurrentToLast();
Kokeile toimiiko lisääminen.
- Lisää myös poista-painike, joka poistaa valittuna olevan ohje-rivin:
System.Windows.Data.CollectionViewSource reseptiOhjeViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("reseptiOhjeViewSource"))); Ohje r = (Ohje)reseptiOhjeViewSource.View.CurrentItem; ohjaus9Entities.DeleteObject(r); ohjaus9Entities.SaveChanges();
Mitä tapahtuu jos muutat poista-painikkeen poistamaan valittuna olevan reseptin? Miksi? Miten ongelma pitäisi kiertää? Kyseessähän on viite-eheyden aiheuttama ongelma ja kaikki ne tietueet pitää poistaa, jotka viittaavat reseptiin.
- Useampi toisiinsa tietokantaoperaatio täytyy suorittaa transaktion sisällä. Kokeile tehdä reseptin poistaminen
seuraavalla tavalla:
// pitää lisätä using System.Transactions sekä references listaan on lisättävä System.Transactions using (TransactionScope scope = new TransactionScope()) // transaktio alkaa { Resepti r = (Resepti)reseptiViewSource.View.CurrentItem; List<Ohje> ohjeet = r.Ohje.ToList<Ohje>(); for (int i = (ohjeet.Count - 1); i >= 0; i--) { ohjaus9Entities.DeleteObject(ohjeet[i]); } List<Liittyy> liittyy = r.Liittyy.ToList<Liittyy>(); for (int i = (liittyy.Count - 1); i >= 0; i--) { ohjaus9Entities.DeleteObject(liittyy[i]); } ohjaus9Entities.DeleteObject(r); ohjaus9Entities.SaveChanges(); scope.Complete(); // transaktio hyväksytään }
- Lisää lomakkeelle päivitä-painike, joka muuttaa valitun reseptin nimeksi Mykykeitto. Muuttaminen tapahtuu samaan tapaan kuin lisääminen ja poistaminenkin.
- Lisää lomakkeelle Tallenna-painike, joka tallentaa tietueisiin tehdyt muutokset. Reseptejä voi suoraan
muokata ikkunassa olevien kenttien avulla mutta muutokset eivät tallennu ilman kutsua:
ohjaus9Entities.SaveChanges();
- Jos haluat tutustua myös Datasetien avulla tapahtuvaan tietokannan käsittelyyn niin kts. vanha pääteohjaustehtävä.
Lisätehtävä
Lisää ikkunaan vielä listaus reseptiin liittyvistä aineista, niiden määristä ja yksiköistä.
Lisätietoa
Seuraavia artikkeleita kannattaa lukea viimeistään demotehtäviä tehdessä.
LINQ insinöörityö
Introduction to the Entity Framework
Converting SQL to LINQ, Part 1: The Basics
Many To Many Mappings in Entity Framework
Many to Many Relationships in the Entity Data Model
Take Row-Level Control of Your GridView
How to: Manage Local Data Files in Your Project
LINQ to SQL - Many to Many Relationships
Concurrency violation: the UpdateCommand affected 0 of the expected 1 records
Käyttäjien kommentit