Avatar
Petr Čech (czubehead):

Ahojte, dělám relativně jednoduchý prográmek, je jedno, co dělá. Narazil jsem ale na následující problém: mám určité datové struktury, které jsou víceméně univerzální (prostě třídy), a chci je ukládat pomocí EF. Problém je to, že se mi nechce třídu, která nemá s databází vůbec nic společného, kromě toho, že ji tam chci uložit, zatěžovat vlastnostmi a atributy, které se využijí jen v EF (třeba ID a pod.). Napadlo mě, že si udělám jiný namesace, kde vytvořím potomky těchto tříd a tam, kde to bude potřeba přidám vlastnosti a atributy navíc. Tyto třídy bych potom ukládal do DB. Jenže to se mi moc dělat nechce, protože se budou motat názvy a pod.

Odpovědět 22.9.2015 20:09
Why so serious? -Joker
Avatar
Milan Křepelka
Redaktor
Avatar
Milan Křepelka:

"Problém je to, že se mi nechce třídu, která nemá s databází vůbec nic společného, kromě toho, že ji tam chci uložit"

Tak to jsem se po ránu opravdu zasmál. Jelikož EF neslouží k ničemu jinému, než k ukládání tříd do databáze, tak mi ten ty tvoje požadavky přijdou úsměvné. Dítě poroditi při tom pannou býti ....

Navíc když je tam budeš chtít uložit, tak je pravděpodobně budeš chtít načíst a nějakým způsobem Identifikovat. Id(jedno číslo) bych tedy nebral jako extra zátěž, navíc se na něj nemusíš až tak vázat

https://msdn.microsoft.com/…j591583.aspx

 
Nahoru Odpovědět 23.9.2015 7:56
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Petr Čech (czubehead)
Jan Vargovský:

Však v aplikaci nepracujes s TOckama, ale s namapovanymi modely.

 
Nahoru Odpovědět 23.9.2015 10:27
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Čech (czubehead)
David Čápka:

Ano, tak je to správně, máš 2 třídy - jednu datovou jen pro EF a druhou aplikační. Datové třídy jsou typicky v jiném NS, dohromady se to nemíchá.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět  +2 23.9.2015 12:58
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na David Čápka
Milan Křepelka:

Myslím, že se pleteš. Velmi těžko můžeš v EF pracovat s dvěma třídama v rámci jednoho SETu. Primárně používám code first, ale co vím, tak model first vygeneruje jednu třídu jako partial "autogenerated" a tu druhou část si děláš jako "partial" součást té autogenerated. Tedy je to jedna třída, která ale fyzicky může být uložena ve více souborech.

 
Nahoru Odpovědět  +1 23.9.2015 14:10
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Petr Čech (czubehead)
Milan Křepelka:

V kontextu Davidova příspěvku mi napadlo, že jsi nenapsal jaký přístup používáš. Pokud nepoužíváš Code First, tak se na něj soustřeď. Balast generuje jenom ten, který si sám napíšeš :-).

 
Nahoru Odpovědět  -1 23.9.2015 14:14
Avatar
Michal Žůrek (misaz):

No já bych to řešil partial třídou. Příjde mi hloupé pak mít vesměs duplicitní třídu, jen kvůli databázi.

Nahoru Odpovědět  ±0 23.9.2015 16:29
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na David Čápka
Petr Čech (czubehead):

takže to bude celé vypadat nějak takto?

public class A
        {
                public string Name { get; set; }
                public int Age { get; set; }
        }

        public class B : A
        {
                [Key]
                public int Id { get; set; }

                [Required]
                [Display(Name = "Name of property")]
                public new int Age { get; set; }

                public B() { }
                public B(A a,int id)
                {
                        PropertyInfo[] aprop = a.GetType().GetProperties();

                        foreach (var info in aprop)
                        {
                                GetType().GetProperty(info.Name).SetValue(this, info.GetValue(a));
                                //zkopírování stejných vlastností
                        }

                        Id = id;
                }
        }

        public class Context : DbContext
        {
                public DbSet<B> Bs { get; set; }
        }

        public static class DB
        {
                public static List<A> LoadAs()
                {
                        using (Context ctx=new Context())
                        {
                                List<A> lst = new List<A>();
                                foreach (B b in ctx.Bs)
                                {
                                        lst.Add(b);
                                }
                                return lst;
                        }
                }

                public static void SaveAs(ICollection<A> col)
                {
                        using (Context ctx = new Context())
                        {
                                ctx.Bs.RemoveRange(ctx.Bs);
                                List<B> lst = new List<B>();
                                for (int i = 0; i < col.Count; i++)
                                {
                                        lst.Add(new B(col.ElementAt(i), i));
                                }

                                ctx.SaveChanges();
                        }
                }
        }

Samozřejmě logika např. ukládání není dokonalá, ale to teď není důležité. A ano, používám code first.

Editováno 23.9.2015 16:36
Nahoru Odpovědět 23.9.2015 16:34
Why so serious? -Joker
Avatar
Lako
Člen
Avatar
Odpovídá na Petr Čech (czubehead)
Lako:

Při použití EF bys měl mít vždycky Modelové třídy. Tedy třídy, které slouží primárně k ukládání do databáze. Defacto to kopíruje tabulku v databázi. Tuto třídu bys měl používat jenom k tahání dat a přesunutí jich do jakého ViewModelu...
Pokud budeš psát trošku složitější aplikaci, tak pořádek který ti to přinese bude daleko cennější, než nízký počet tříd/souborů.
Databázové třídy bys měl mít ve složce Models, popřípadě celou práci s dtb přesunutou do samostatného projektu (u větších aplikací) - a celé ti to pomůže vyvarovat se referencím v databázovém projektu na hlavní projekty (což je dobře)...
Je to prostě jenom návrhový vzor, který se vyplatí častokrát respektovat.

 
Nahoru Odpovědět 23.9.2015 16:34
Avatar
Milan Křepelka
Redaktor
Avatar
Milan Křepelka:

Dlouho na to koukám. A nevím co mi na tom vadí. V původním příspěvku jsem si nevšiml tý dědičnosti a ani tak mi to nepřide moc dobrý nápad. Mám k tomu nějaký přirozený odpor. Ničeho valného nedosáhneš, tedy kromě toho že budeš mít jednu třídu navíc.

Proč tam máš vlastně toto ?

[Required]
[Display(Name = "Name of property")]
public new int Age { get; set; }

Myslím, že to je dobrý příklad programovat přes rozhraní. Ty se chceš vlastně nutně odstínit od databázového "bordelu".

Ven mimo ten databázový svět vytáhneš rozrhaní IA které bude mít tu stejnou signaturu jako třída A a budeš pracovat s rozhraním. Dosáhl jsi téhož při jedné třídě. S benefity programování přes rozhraní.

Ta DB logika nic moc. V podstatě by se dalo říct, že DB nepotřebuješ. Stačila by ti serializace objektů do souboru a takovýhle věci bys nemusel vůbec řešit s minimální pracností i toho ukládání. Tedy pokud DB neslouží i pro jiné části většího řešení.

 
Nahoru Odpovědět  +1 23.9.2015 18:33
Avatar
Odpovídá na Milan Křepelka
Petr Čech (czubehead):

Vzhledem k tomu, že A má určitou funkcionalitu, tak rozhraní bohužel asi těžko.

[Required]
[Display(Name = "Name of property")]
public new int Age { get; set; }

Tohle je ukázka toho, jak natahám databázový bordel do modelu bez toho, aniž by se to povalovalo v samotném A.
A ano, klidně bych mohl použít serializaci do souboru, spíš mě zajímalo, jak má být správně, navíc se nemusím starat o takové kraviny jako uživatelská práva v adresářích, neexistující složky etc.
Databázová logika v příkladu je narychlo splácaná, ve výsledku to vylepším.

Nahoru Odpovědět 23.9.2015 18:53
Why so serious? -Joker
Avatar
Milan Křepelka
Redaktor
Avatar
Milan Křepelka:

To se vůbec nevylučuje. Ty bys používal IA, ale ve skutečnosti to jsou objekty B do kterých bys tu logiku samozřejmě napsal. Objekt A by vůbec neexistoval.

Už jsem přišel na to co mi na tom vadí.Tohle není moc dobrý příklad jako používat "jednonásobnou" dědičnost. Je to vlastně pojmutý tak nějak obráceně.

Ty objektům na "konci" řetězce v hiearchii dědičnosti, přidáváš funcionalitu kterou by měly mít společnou... umění se uložit do DB.

Tedy budeš mít N tříd, které budou mít to samé.

[Key]
                public int Id { get; set; }

Přitom "normálně" by měla existovat jedna třída s Id od které by ostatní dědily.

 
Nahoru Odpovědět 23.9.2015 19:25
Avatar
Jakub Šárník:

Nevím, proč by měl být problém mít prostě jednu třídu, bez dalších zbytečných potomků nebo rozhraní. Pokud chceš něco ukládat do databáze, tak říct že to s ní nesouvisí je snad oxymóron :-P

 
Nahoru Odpovědět  +1 23.9.2015 19:44
Avatar
Odpovídá na Milan Křepelka
Petr Čech (czubehead):

Ale to bych měl zase všude vlastnost Id, která nemá se samotnou třídou nic společného.

Nahoru Odpovědět 23.9.2015 19:52
Why so serious? -Joker
Avatar
Odpovídá na Jakub Šárník
Petr Čech (czubehead):

Nejde o to, že by to nešlo, samozřejmě to jde, ale třída např. uživatel by neměla vědět o tom, že je určená k uložení v databázi, to by se mělo řešit mimo ní.

Nahoru Odpovědět 23.9.2015 19:54
Why so serious? -Joker
Avatar
Odpovídá na Petr Čech (czubehead)
Jakub Šárník:

Chápu, ale zdá se mě to zbytečné. Naopak, podle mě by třída uživatel měla vědět, že je určená k uložení v databázi, přijde mě úplně zcestné to řešit jinde

 
Nahoru Odpovědět 23.9.2015 20:01
Avatar
patrik.valkovic
Šéfredaktor
Avatar
Odpovídá na Jakub Šárník
patrik.valkovic:

Na jednu stranu souhlasím, třída User by vážně neměla vědět, že je určena k uložení k databázi. Dávalo by tedy smysl od ní dědit třídu, která by počítala s tím, že bude uložena v databázi.
Ale s pár výhradami - neměla by jít vytvořit v aplikaci. S odvozenou třídou by mělo jít pracovat pouze tam, kde se pracuje zároveň s databází. Ale jak to vyřešit, mě moc nenapadá. Skrýt konstruktor, vytvořit faktorku. Eventuelně použít jiné assemble?

Nahoru Odpovědět 23.9.2015 20:05
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Jan Vargovský:

Hloupé to není. Až budeš mít model, který třeba bude reprezentovat nějakého usera, tak bude mít x atributů a ve view budeš zobrazovat jeden z nich, taky budeš pořád pracovat s tím TOčkem? To je celkem bad practice. Vždycky vytáhneš data z db a přemapuješ to na model, který je 1:1 ke tvému view.

Editováno 23.9.2015 20:48
 
Nahoru Odpovědět 23.9.2015 20:46
Avatar
Odpovídá na patrik.valkovic
Jakub Šárník:

Zdá se mě, že poslední dobou lidi vážně vymýšlí příliš komplikovaná řešení na triviální problémy...

 
Nahoru Odpovědět  +1 23.9.2015 21:38
Avatar
patrik.valkovic
Šéfredaktor
Avatar
Odpovídá na Jakub Šárník
patrik.valkovic:

Jako z hlediska správného návrhu programu to smysl dává. Otázka je, jestli si tím komplikovat práci.

Nahoru Odpovědět 23.9.2015 21:44
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

Ne, to je špatný přístup, míchat se to nesmí. View by nemělo přistupovat vůbec k entitám, někdy se na to používá automapper, někdy se to mapuje ručně. Každopádně na to máš ViewModely. Do EF tříd se také nepíše logika, je rozdíl mezi datovým a doménovým modelem. máš tu tedy Entitu, Model a ViewModel - 3 různé věci, které se někdy míchají dokonce do jedné. mají být ale oddělené, to jsou best practices. Doporučuji si o tom něco nastudovat, není to úplně triviální záležitost. Zde jsou nějaké odkazy:

http://stackoverflow.com/…siness-logic

I would keep my Entities as POCO's(Plain Old Class Objects, classes with only properties) and have a Repositary do methods like Insert / Update.

http://cpratt.co/…-not-models/
http://www.codeguru.com/…ications.htm
https://www.google.cz/webhp?…

Bude tu na to seriál.

Nahoru Odpovědět  +1 23.9.2015 22:45
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Jan Vargovský
Milan Křepelka:

Co to je TOčko. To bude nějaká super zkratka?

Editováno 24.9.2015 7:33
 
Nahoru Odpovědět 24.9.2015 7:32
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na David Čápka
Milan Křepelka:

Jednáte z přesvědčení, že vůbec dělá nějakou MVC aplikaci. Není vůbec zřejmé že potřebuje zvtah DB (Entita,Model), ViewModel.

 
Nahoru Odpovědět 24.9.2015 7:57
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Milan Křepelka
Jan Vargovský:

Transfer Object. Normální zkratka každého developera.

 
Nahoru Odpovědět 24.9.2015 8:15
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Jan Vargovský
Milan Křepelka:

Raději používej celá slova. Hovoříš k lidem, kteří je nejspíš je nebudou znát. Jo a normální developeři používají DTO jako Data Tranfer Object. To tvoje TO je "self made" zkratka.

 
Nahoru Odpovědět  +1 24.9.2015 8:40
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

MVC je dnes již všude, ať dělá ASP nebo WPF.

Nahoru Odpovědět 24.9.2015 9:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na David Čápka
Milan Křepelka:

To je implikace postavená na vodě. Napsal že dělá jednoduchý prográmek. Tahat to toho tyhle vzory bude spíše zbytečnost. MVC je ve WPF je spíše podivný návštěvník. Nicméně je pravda, že ta "modelová" část je s MVVM prakticky stejná záležitost.

 
Nahoru Odpovědět  +1 24.9.2015 9:17
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

Není to podivný návštěvník, ale základní princip toho, jak ten framework funguje.

Nahoru Odpovědět 24.9.2015 9:28
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na David Čápka
Milan Křepelka:

Pouze pokud si pleteš MVC a MVVM.

 
Nahoru Odpovědět 24.9.2015 9:31
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

Aha a ta vrstva s CodeBehind je co? Pracuje s logikou a předává ji pohledu (XAMLu), nedělá to náhodou kontroler? :-` Že se to tak nejmenuje neznamená, že to není MVC architektura.

Nahoru Odpovědět 24.9.2015 9:36
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Jakub Šárník:

Popravdě, já osobně nevidím problém s business logikou v entitách a zdá se mě, že tyhle samý návrhový vzory to jenom komplikujou a výhody nepřidávají

 
Nahoru Odpovědět 24.9.2015 9:39
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jakub Šárník
David Čápka:

Dělej si to jak chceš, třeba si to piš neobjektově. My se jen vyjadřujeme k tomu, jak se tom má dělat správně. A komplikované to není, je to jednoduché rozdělení.

Nahoru Odpovědět 24.9.2015 9:41
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Milan Křepelka:

Autobus není auto i přes to, že má 4kola a motor. MVC, MVP, MVVM jsou stejná rodina, ale ty rozdíly jsou určující právě z pohledu technologie kterou zajišťije databinding ve WPF. Hovořit o MVC se spojením s WPF je lehce mimo. Měl by sis všimnout, že mnoho ostatních mezi tím vidí rozdíly.

 
Nahoru Odpovědět 24.9.2015 9:50
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

Tady si nerozumíme, já neříkám, že MVC a MVVM je to samé. Já říkám, že ve WPF máš principy MVC i MVVM. Stejně jako tomu tak je v ASP.NET.

Nahoru Odpovědět 24.9.2015 9:52
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na David Čápka
Jakub Šárník:

Jak se to dělat má... No i na stackoverflow se o tom lidi hádají a sice je pravda že převládá názor, že z hlediska puristického přístupu by odděleny být měli, tak z hlediska pragmatismu nemusí. Zvlášť pokud jde o menší aplikaci. Někteří lidé říkali i to, že právě v EF je možné mít to v jedné entitě a že je na to EF i připravenej

 
Nahoru Odpovědět 24.9.2015 10:01
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Jakub Šárník
David Čápka:

Lidé se hádají pořád, na základě toho bych si určitě nestavěl názor ;-) Mně je to jedno, napsal jsem vám jak to je správně, dělejte si to jak chcete, to už je vaše věc, vaše projekty a vaše chyby.

Nahoru Odpovědět 24.9.2015 10:03
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na Jakub Šárník
Milan Křepelka:

O to taky problém není. Dělat jakousi zcela prázdou "Entitu" abys ji mohl podědit a napsat do ní nějakou logiku je pitomost. Nedádá to elementární smysl.

 
Nahoru Odpovědět 24.9.2015 10:04
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

Z té entity se nedědí, jaký by to mělo smysl? Nejčastěji máš Entitu, ViewModel a repozitář.

Nahoru Odpovědět 24.9.2015 10:12
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Milan Křepelka
Redaktor
Avatar
Odpovídá na David Čápka
Milan Křepelka:

Ale o tom je tento dotaz. Uživatel dělá potomky tříd a tys mu tento postup vlastně potvrdil. Ale jinak si myslím, že z větší části rozporů jde o zmatení pojmosloví mezi "entitou", modelem, viewmodelem a dokonce se nám tu objevili DTO objekty.

Nejlepší na toto je, je praxe. Pak si člověk uvědomí co je co. Míru odpovědnosti a názor si utříbí vlastně sám.

 
Nahoru Odpovědět  +1 24.9.2015 10:22
Avatar
Milan Křepelka
Redaktor
Avatar
 
Nahoru Odpovědět 24.9.2015 10:28
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Křepelka
David Čápka:

To potvrzení jsem myslel na to, že to má oddělit. Děděním se nic nevyřeší, je to to samé jako by to napsal do jednoho nebo udělal partial. Máš pravdu, že z této diskuze nejde moc poznat jak to má tedy být, padlo tu spoustu pojmů, tohle je problematika na celý seriál, který se mimochodem sepisuje, je asi z 50% hotový.

Editováno 24.9.2015 10:32
Nahoru Odpovědět  +1 24.9.2015 10:31
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Petr Čech (czubehead):

Děkuji všem za zpětnou vazbu. Vzhledem k tomu, že ta appka je opravdu jednoduchá (3 "hlavní" třídy), napíšu to prostě do těch tříd a až budu dělat něco složitějšího, budu to dělat správně. Jsem si vědom toho, že to je z hlediska návrhu špatně, ale moc nevěřím tomu, že u této konkrétní aplikace by to byl problém. Až bude hotový seriál, rád si ho přečtu.

Nahoru Odpovědět 24.9.2015 14:19
Why so serious? -Joker
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 43 zpráv z 43.