NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Karta klienta - má první aplikace

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Neaktivní uživatel:10.7.2017 9:34

Ahoj, jsem tu úplně nový a zatím se prokousávám všemi tutoriály, ale měl bych dotazy k aplikaci, kterou teď píšu. Základním kamenem té aplikace je již z existující databáze si stáhnout informace o zákazníkovi na základě zadaného ID objednávky.
Bohužel databáze je ve strašném stavu (tabulky mají +40 sloupců. postrádá kompletně cizí klíče, pojmenování jsou často nejasná a duplicitní). Jelikož jsem začátečník a umím jen trošičku C# vydal jsem se cestou entity frameworku. Na základě tutoriálů na UDEMY a tady jsem nakonec vše rozchodil a úspěšně stahuji data z databáze. Rád bych kdyby jste se vyjádřili k mému postupu. Zda sem k celé věci přistoupil správně, nebo co by šlo udělat lépe?
Vytvoření modelu a mapování sem nechal na Visual studiu.
Následně jsem vytvořil třídu správce.

  class Spravce
{
    /// <summary>
    /// Relace k databázi
    /// </summary>
    public Entities DAT;
    /// <summary>
    /// Třída obsahující info k zákazníkovy
    /// </summary>
    public Zakaznik zakaznik;

    public Spravce(int idObjednavky)
    {
        using (DAT = new Entities())
        {
            zakaznik = new Zakaznik(idObjednavky, DAT);
        }

    }

Následně sem si vytvořil třídu zakaznik, které předávám objekt DAT a ID objednávky podle, kterého budu hledat zákazníka v databázi.

    class Zakaznik
    {
        /// <summary>
        /// ID Objednávky
        /// </summary>
        public int IdObjednavky { get; private set; }
        /// <summary>
        /// Jméno zákazníka
        /// </summary>
        public string Jmeno { get; private set; }
        /// <summary>
        /// Příjmení zákazníka
        /// </summary>
        public string Prijmeni { get; private set; }

 /// <summary>
        /// Konstrukor - převezme ID objednávky a relaci k DB
        /// </summary>
        /// <param name="id"></param>
        /// <param name="DAT"></param>
        public Zakaznik(int id, Entities DAT)
        {
            this.IdObjednavky = id;
            Napln(DAT);
        }
/// <summary>
        /// Metoda na naplnění třídy - převezme si relaci k DB
        /// </summary>
        /// <param name="DAT"></param>
        private void Napln(Entities DAT)
        {

            ///Najdi Objednávku
            var objednavka = (from o in DAT.objednavky
                                     where o.Id_objednavky == IdObjednavky
                                     select o).First();

            ///Najdi zákazníka
            var zakaznik= (from zk in DAT.zakaznici
                                  where zk.Id_zakaznika == objednavka.Id_zakaznika
                                  select zk).First();
            Jmeno = zakaznik.Jmeno;
            Prijmeni = zakaznik.Prijmeni;

Třída zakazník je ve skutečnosti ještě delší, protože tahám vedle jména +dalších 15 parametrů z přibližně 10ti tabulek. Celá aplikace funguje bezproblémově a data se stáhnou z db v rámci 4-6 vteřin.
Mojí otázkou je, šlo by to udělat rychleji a lépe? Bylo by řešením nahradit ty zdlouhavé linq výrazy lambda? Nebo bylo by rychlejší stáhnout data pomocí jednoho složitějšího SQL dotazu do datagridu a pak si to sebrat?

Editováno 10.7.2017 9:36
Odpovědět
10.7.2017 9:34
Neaktivní uživatelský účet
Avatar
Lako
Člen
Avatar
Lako:10.7.2017 14:16

Moc mi není jasné o co přesně se snažíš?
Snažíš se nějak zduplikovat tu databázi do rozumnější struktury, nebo se jenom snažíš vytáhnout z té existující databáze zákazníky a na ničem jiném ti nezáleží?

 
Nahoru Odpovědět
10.7.2017 14:16
Avatar
Neaktivní uživatel:10.7.2017 14:21

Snažím se vytáhnout jen zákazníky a info o nich, bohužel je to různě rozházené.
Napadlo mě také co by mohlo podstatně celý proces urychlit....
Momentálně mám model generovaný z databáze - jenže tento model zahrnuje stovky polí - zatímco moje aplikace využije jen 1/4 možná méně. Je možné z modelu ty pole odstranit, tedy aby .edmx model zahrnoval jen pole, která potřebuji pro aplikaci?

Nahoru Odpovědět
10.7.2017 14:21
Neaktivní uživatelský účet
Avatar
Neaktivní uživatel:10.7.2017 14:53

Jinak tedy...Musím za použití entity frameworku stahovat všechna pole tabulek s kterými budu pracovat? Pokud ne, tak jak určím s kterými poli budu pracovat? Entity framework mě vygeneroval model na základě databáze tedy...

  • Mohu z modelu účinně odstranit pole, která nepotřebuji aby se nestehovala a já dosáhl zvýšení rychlosti?
  • Nebo musím použít Code First a napsat si to celé sám?

Pokud oboje, tak co je lepší?

Případně nebylo by lepší použít SQL a stáhnout data do data gridu?

Nahoru Odpovědět
10.7.2017 14:53
Neaktivní uživatelský účet
Avatar
zelvicek
Člen
Avatar
zelvicek:10.7.2017 14:59

Zdravím,
ke kódu mám pár komentářů:

  1. k čemu je public Entities DAT; ? Nevidím pro to žádný logický účel, zrušil bych to.
  2. netahal bych logiku načítání dat do datové třídy (.ctor + Napln) - na to by měla být nějaká servisní třída static/factory/ser­viceProvider.
  3. Zakaznik..ctor - název parametru "id" ve mě evokuje id-zákazníka, nikoliv objednávky.
  4. Nevím, jak máš zajištěno, že objednávka s daným ID jistojistě existuje a že ti aplikace nespadne při volání ...select o).First();, ale budiž. Každopádně jsem už viděl spoustu promarněných hodin zjišťováním příčiny chyby "Collection doesn't contain an element" - tu hlášku si nepamatuju přesně, ale rozhodně není hned zřejmé, že se jedná o nenalezenou objednávku v DB.
  5. V obou SQL dotazech načítáš všechny sloupce daného řádku zbytečně. Lepší je načítat jen ty (domněle) potřebné.
  6. Sloučením SQL dotazů by jsi jistě pár milisekund ušetřil.
  7. ta "rychlost" 4-6 sekund mi přijde příšerná -> nechybí v tabulkách indexy?
  8. to mapování propert objektu zákazník je podivné, má to nějaký business/archi­tecture význam?
 
Nahoru Odpovědět
10.7.2017 14:59
Avatar
zelvicek
Člen
Avatar
Odpovídá na Neaktivní uživatel
zelvicek:10.7.2017 15:04

Případně nebylo by lepší použít SQL a stáhnout data do data gridu?

Předpokládám, že SQL už používáš, zde jsi asi měl na mysli ADO.NET. Datagrid určitě ne, spíše IDataReader.

 
Nahoru Odpovědět
10.7.2017 15:04
Avatar
Odpovídá na zelvicek
Neaktivní uživatel:10.7.2017 16:15

Díky moc za odpověď..

1. Smazal jsem - máš pravdu
2. Tomuto moc nerozumím - dokázal by si mě odkázat na nějaký naučný materiál, příp. příklad?
3. Používám stejná názvosloví jako databáze - to, že jsou špatně je věc jiná. Bohužel nad databází nemám práva
4. Používám try-catch
5. Přišel sem konečně na to, jak využít code first from the database
6-7 I přestože nyní tahám jen ty sloupce, které potřebuji načítání je 3 sekundy - kdybych pro stejný typ dotazu použil sql v sql management studiu trval by necelou sekundu - nevím kde dělám chybu.
8. Databáze jde mimo mě, musím se jí přizpůsobit

Nahoru Odpovědět
10.7.2017 16:15
Neaktivní uživatelský účet
Avatar
zelvicek
Člen
Avatar
zelvicek:11.7.2017 7:19

1. Fajn :-)
2.

public class Zakaznik
{
        public int IdObjednavky { get; private set; }
        public string Jmeno { get; private set; }
        public string Prijmeni { get; private set; }
}

public static class ZakaznikRepository
{
        public static Zakaznik LoadByOrder(int idOrder)
        {
                var id_zakaznika = (from o in DAT.objednavky
                                     where o.Id_objednavky == IdObjednavky
                                     select o.Id_zakaznika).First;

            ///Najdi zákazníka
            return (from zk in DAT.zakaznici
                                  where zk.Id_zakaznika == id_zakaznika
                                  select zk).First();
        }
}
 
Nahoru Odpovědět
11.7.2017 7:19
Avatar
Neaktivní uživatel:11.7.2017 12:05

ok...Možná sem to pochopil....hned pošlu zdroják.

Editováno 11.7.2017 12:07
Nahoru Odpovědět
11.7.2017 12:05
Neaktivní uživatelský účet
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 9 zpráv z 9.