Letní akce! Lákají tě IT školení C#, Javy a PHP v Brně? Přihlas se a napiš nám do zpráv kód "BRNO 500" pro slevu 500 Kč na libovolný brněnský kurz. Lze kombinovat se slevami uvedenými u školení i použít pro více kurzů. Akce končí 28.7.

Lekce 13 - Diář s databází v C#

C# .NET Objektově orientované programování Diář s databází v C# American English version English version

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, List, jsme si ukázali kolekci List. Víme, že nám oproti poli umožňuje přidávat nové prvky za běhu programu a nemusíme se starat o jeho velikost. Dnes si v C# tutoriálu do Listu zkusíme uložit objekty.

Prvně jsem chtěl udělat databázi uživatelů, ale uživatele jsme tu již několikrát měli. Jelikož jsme se nedávno naučili datum a čas, naprogramujeme si diář. Do databáze budeme ukládat jednotlivé záznamy a vždy vypíšeme ten dnešní a zítřejší. Databáze to nebude samozřejmě ta v tom pravém slova smyslu (na to ještě nemáme zkušenosti), ale bude se jednat právě o List v operační paměti počítače. Bude umožňovat záznamy přidávat, hledat je podle data a mazat podle data a času.

Založte si nový projekt, který pojmenujeme Diar.

Záznam

Prvně si udělejme třídu, jejíž instance budeme ukládat. Nazvěme ji Zaznam. Záznam v diáři se bude vázat k nějakému datu a času. Také bude obsahovat nějaký text. Např.: "12. ledna 2018 - Vyvenčit psa". To je asi vše, třída může vypadat takto:

class Zaznam
{
        public DateTime DatumCas { get; set; }
        public string Text { get; set; }

        public Zaznam (DateTime datumCas, string text)
        {
                DatumCas = datumCas;
                Text = text;
        }

        public override string ToString()
        {
                return DatumCas + " " + Text;
        }
}

Třída v podstatě slouží jen k záznamu dat a nemá žádné metody (až na konstruktor a ToString()). Všimněte si, že v konstruktoru již nemusíme používat this, jak jsme byli zvyklí u atributů, protože nyní se jedná o vlastnosti s velkými písmeny.

Databáze

Protože program bude o něco složitější, rozdělíme ho do více objektů (vrstev). Záznam máme, nyní si vytvoříme objekt Databaze, ve které budou záznamy uloženy. Opět bude mít privátní List, jako měl Losovac. Ten bude nyní typu Zaznam. Diář bude umožňovat záznamy přidávat, mazat a vyhledávat podle data. K projektu tedy přidáme třídu Databaze. Bude velmi podobná minulému Losovači:

class Databaze
{
        private List<Zaznam> zaznamy;

        public Databaze()
        {
                zaznamy = new List<Zaznam>();
        }

}

Třída tedy slouží pouze pro manipulaci s daty. Obsahuje vnitřní kolekci zaznamy, ta se inicializuje v konstruktoru. Mohli bychom použít i inicializaci bez konstruktoru přímo u deklarace ve formě:

private List<Zaznam> zaznamy = new List<Zaznam>();

Dodejme třídě metody pro přidání, vymazání a vyhledání záznamu. Přidání záznamu by mělo být jasné:

public void PridejZaznam(DateTime datumCas, string text)
{
        zaznamy.Add(new Zaznam(datumCas, text));
}

Jako druhou metodu přidejme nalezení záznamů v daný den. Metoda bude vracet List nalezených záznamů, protože jich pro ten den může být v databázi více. Záznamy budeme moci vyhledávat podle data i času nebo jen podle data. Můžeme tak najít záznamy v konkrétní den bez ohledu na to, v jakou jsou hodinu. Podle čeho budeme chtít vyhledávat bude udávat parametr dleCasu typu bool. Pokud bude false, hledáme jen podle data bez ohledu na čas. List si nejprve vytvoříme a poté do něj přidáváme záznamy, které odpovídají hledanému datu. Odpovídat musí buď celé datum a čas (pokud hledáme i podle času) nebo jen část Date, pokud hledáme jen podle data. Naplněný List s nalezenými záznamy vrátíme.

public List<Zaznam> NajdiZaznamy(DateTime datum, bool dleCasu)
{
        List<Zaznam> nalezene = new List<Zaznam>();
        foreach (Zaznam z in zaznamy)
        {
                if (((dleCasu) && (z.DatumCas == datum)) // dle času a data
                ||
                ((!dleCasu) && (z.DatumCas.Date == datum.Date))) // pouze dle data
                        nalezene.Add(z);
        }
        return nalezene;
}

Nakonec přidáme vymazání záznamů v určitou dobu. To provedeme pomocí metody NajdiZaznamy() a nalezené záznamy jednoduše proiterujeme a z Listu odstraníme. Budeme mazat podle přesného data i času, 2. parametr u metody NajdiZaznamy() bude tedy true:

public void VymazZaznamy(DateTime datum)
{
        List<Zaznam> nalezeno = NajdiZaznamy(datum, true);
        foreach (Zaznam z in nalezeno)
                zaznamy.Remove(z);
}

Diář

Nyní si přidáme k projektu poslední třídu, bude to samotný diář. Nazvěme ji Diar. Ten již bude obsahovat metody pro komunikaci s uživatelem. Všimněte si, jak aplikaci rozdělujeme a jednotlivé její části zapouzdřujeme. List je zapouzdřen v databázi, která nad ním postavila další metody pro bezpečnou manipulaci s jeho obsahem. Samotnou databázi nyní vložíme do diáře. Tím oddělíme logiku a práci s daty od komunikace s uživatelem a dalšími vstupy/výstupy programu. Třída Diar tedy bude komunikovat s uživatelem a data od něj předá databázi.

Přidejme si privátní instanci databáze, kterou si vytvoříme v konstruktoru:

class Diar
{

        private Databaze databaze;

        public Diar()
        {
                databaze = new Databaze();
        }

}

Jako další přidejme pomocnou metodu ZjistiDatumCas(), která vyzve uživatele k zadání data a času a vrátí instanci DateTime nastavenou na tuto hodnotu. Jediným bodem k přemýšlení je zde validace vstupu od uživatele:

private DateTime ZjistiDatumCas()
{
        Console.WriteLine("Zadejte datum a čas ve tvaru [1.1.2012 14:00]:");
        DateTime datumCas;
        while (! DateTime.TryParse(Console.ReadLine(), out datumCas))
                Console.WriteLine("Chybné zadání, zdajte znovu datum a čas: ");
        return datumCas;
}

Přidejme metodu VypisZaznamy(), která najde záznamy v daný den a vypíše je:

public void VypisZaznamy(DateTime den)
{
        List<Zaznam> zaznamy = databaze.NajdiZaznamy(den, false);
        foreach (Zaznam z in zaznamy)
                Console.WriteLine(z);
}

Metoda pro vyzvání uživatele k vložení parametrů nového záznamu a jeho přidání do databáze bude následující:

public void PridejZaznam()
{
        DateTime datumCas = ZjistiDatumCas();
        Console.WriteLine("Zadejte text záznamu:");
        string text = Console.ReadLine();
        databaze.PridejZaznam(datumCas, text);
}

Zbývá záznamy vyhledávat a mazat. Metoda k vyhledání vrátí List s nalezenými záznamy (jen podle data, přesný čas nebude hrát roli). Vyzveme uživatele k zadání data a to předáme databázi. Výsledek zobrazíme.

public void VyhledejZaznamy()
{
        // Zadání data uživatelem
        DateTime datumCas = ZjistiDatumCas();
        // Vyhledání záznamů
        List<Zaznam> zaznamy = databaze.NajdiZaznamy(datumCas, false);
        // Výpis záznamů
        if (zaznamy.Count() > 0)
        {
                Console.WriteLine("Nalezeny tyto záznamy: ");
                foreach (Zaznam z in zaznamy)
                        Console.WriteLine(z);
        }
        else
                // Nenalezeno
                Console.WriteLine("Nebyly nalezeny žádné záznamy.");
}

Mazání záznamů je triviální:

public void VymazZaznamy()
{
        Console.WriteLine("Budou vymazány záznamy v daný den a hodinu");
        DateTime datumCas = ZjistiDatumCas();
        databaze.VymazZaznamy(datumCas);
}

Jako poslední přidejme metodu pro vypsání úvodní obrazovky programu s aktuálním datem a časem a událostmi na dnešek a zítřek.

public void VypisUvodniObrazovku()
{
        Console.Clear();
        Console.WriteLine("Vítejte v diáři!");
        Console.WriteLine("Dnes je: {0}", DateTime.Now);
        Console.WriteLine();
        // výpis hlavní obrazovky
        Console.WriteLine("Dnes:\n-----");
        VypisZaznamy(DateTime.Today);
        Console.WriteLine();
        Console.WriteLine("Zítra:\n------");
        VypisZaznamy(DateTime.Now.AddDays(1));
        Console.WriteLine();
}

Můžeme vítězoslavně přejít do Program.cs a vytvořit instanci diáře. Zde umístíme také hlavní cyklus programu s menu programu a reakcí na volbu uživatele. Je to ta nejvyšší vrstva programu:

static void Main(string[] args)
{
        // instance diáře
        Diar diar = new Diar();
        char volba = '0';
        // hlavní cyklus
        while (volba != '4')
        {
                diar.VypisUvodniObrazovku();
                Console.WriteLine();
                Console.WriteLine("Vyberte si akci:");
                Console.WriteLine("1 - Přidat záznam");
                Console.WriteLine("2 - Vyhledat záznamy");
                Console.WriteLine("3 - Vymazat záznam");
                Console.WriteLine("4 - Konec");
                volba = Console.ReadKey().KeyChar;
                Console.WriteLine();
                // reakce na volbu
                switch (volba)
                {
                        case '1':
                                diar.PridejZaznam();
                                break;
                        case '2':
                                diar.VyhledejZaznamy();
                                break;
                        case '3':
                                diar.VymazZaznamy();
                                break;
                        case '4':
                                Console.WriteLine("Libovolnou klávesou ukončíte program...");
                                break;
                        default:
                                Console.WriteLine("Neplatná volba, stiskněte libovolnou klávesu a opakujte volbu.");
                                break;
                }
                Console.ReadKey();
        }
}

Kód výše není složitý a již jsme tu podobný měli mockrát. Výslednou aplikaci jsem na vyzkoušení půjčil přítelkyni, zde vidíte výsledek :) :

Konzolová aplikace
Vítejte v diáři!
Dnes je: 13.6.2016 20:22:45

Dnes:
-----
13.6.2016 10:00:00 Shopping - Arkády Pankrác
13.6.2016 19:30:00 Vyvenčit mého yorkšírka Dennyho

Zítra:
------
14.6.2016 14:00:00 Power plate

Vyberte si akci:
1 - Přidat záznam
2 - Vyhledat záznamy
3 - Vymazat záznam
4 - Konec
2
Zadejte datum a čas ve tvaru [1.1.2012 14:00]:
15.6.2016
Nalezeny tyto záznamy:
15.6.2016 9:30:00 Zkouška - Ekonomika cestovního ruchu

Tímto jsme si List osvojili a bude nám poměrně dlouho stačit. Na závěr bych dodal, že takto si můžete udělat databázi čehokoli. Můžete použít např. třídu Uzivatel z lekce Vlastnosti nebo kteroukoli jinou třídu. Můžete ukládat články, úlohy, slony, cokoli, co chcete v databázi spravovat. A co dál? V příští lekci, Rozhraní (interface), to bude o rozhraní. V OOP nás toho čeká ještě dost :)


 

Stáhnout

Staženo 914x (34.68 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
24 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Předchozí článek
List
Miniatura
Následující článek
Cvičení k 12.-13. lekci OOP v C# .NET
Aktivity (9)

 

 

Komentáře
Zobrazit starší komentáře (24)

Avatar
Michal Štěpánek:11.2.2016 8:53
8-)
Odpovědět  +1 11.2.2016 8:53
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Honza Rada
Člen
Avatar
Honza Rada:6.5.2017 6:50

Nevýhoda je že se záznamy neuloží no nic, tak to uďělám až dojdu k seriálu a souborech a jinak super tutoriál, jako vždy :-)

Odpovědět 6.5.2017 6:50
#c#
Avatar
Riči Jak
Člen
Avatar
Riči Jak:22.9.2017 10:01

Pěkný projektík, palec nahoru :-)

 
Odpovědět 22.9.2017 10:01
Avatar
Ondřej Čech:16.11.2017 23:07

Myslím, že DateTime.Now je na místě, protože tě zajímá i aktuální čas. DateTime.Today ti nastavi cas na pulnoc. Tže třeba v 15:00 když bys zapnul aplikaci, už tě nemusí zajímat, co bylo v 8 ráno. Ale to je kosmetická úprava a ne chyba. Kód jsem celý psal sám podle článku a fungovalo mi vše.

Jinak krásná ukázka OOP. Sám bych asi Diář bral už jako databázi(čili jen 2 třídy) a v mainu bych měl trošku větší nepořádek s komunikací s uživatelem.. Toto mi dost pomohlo proniknout dále do OOP. =)

 
Odpovědět 16.11.2017 23:07
Avatar
Michaela Radimská:22. března 16:19

Mám trochu chaos v tom, co psát do Main a co ne. Proč je ten while cyklus v Main a není jako metoda ve třídě Diář, odkud by se v Main jenom zavolal? Ve škole nám říkají, aby bylo v Main minimum kódu (skoro nic), ale nevím, podle čeho se nějak logicky orientovat... :-S

 
Odpovědět 22. března 16:19
Avatar
Filip Němeček
Redaktor
Avatar
Odpovídá na Michaela Radimská
Filip Němeček:22. března 16:43

To bude hlavně z důvodu, že se tento tutoriál věnuje Listu jako kolekci a pro zjednodušení je cyklus přímo v Main. Obecně tedy platí, že v Main by skutečně mělo být minimum kódu. Navíc, jakmile začneš dělat okenní aplikace (tedy to, co se normálně používá), tak už ani Main metoda nebude :-)

 
Odpovědět 22. března 16:43
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Michaela Radimská
pocitac770:22. března 16:46

Protože funkcí diáře není s námi komunikovat, diář je od toho, aby ukládal data, aby to byla určitá datová struktura (Jako například ArrayList), kterou lze použít v mnoha různých situacích, třeba i jinde než v této aplikaci... a tam zase budeme mít jinou komunikaci, třeba ne přes konzoli, ale přes okenní aplikaci. Ano, v main by mělo být minimum kódu, ale měla by jsi rozlišovat co patří k čemu. Můžeš si udělat objekt, který bude zajišťovat dialog (hm... jak ho pojmenovat, třeba... Dialog? :D to je krása OOP, jednoduché vymýšlení jmen, prostě Třídu pojmenuješ podle toho, k čemu je určená, a taky se toho držíš -> nepoužíváš ji na nic jiného). Jednou z vlastností OOP je právě znovupoužitelnost, kterou pak později můžeš použít v praxi, když budeš pracovat na hodně podobných projektech.. prostě použiješ starou třídu a máš vystaráno :)

 
Odpovědět 22. března 16:46
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na pocitac770
pocitac770:22. března 16:57

//EDIT
List, ne ArrayList, tohle je vlastně C# :D

Editováno 22. března 16:57
 
Odpovědět 22. března 16:57
Avatar
Michaela Radimská:24. března 14:50

Díky Filip Němeček a pocitac770 :-)

 
Odpovědět 24. března 14:50
Avatar
Andy Scheuchzer:21. dubna 18:35

Skvělý prográmek, ale pár úprav s dosavadními vědomostmi by se našlo (samozřejmě vždy :-) )

Odpovědět 21. dubna 18:35
Od ASM úroveň jazyků pouze klesá…
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 34. Zobrazit vše