Archtektura DTO, Repo,... a "dynamické data" rubrika: Programování: .Net

4 pilif
položil/-a 27.6.2018

Zdravím ve spolek,
potřebuji radu :)

Máme architekturu:

  • DAL/Entity Framework
  • Repositories
  • Facades
  • WebAPI

Tenký klient běží jako WPF Desktop MVVM.
Data putují z repozitářů přes WebAPI až na klienta ve formě DTO.

Problém:
Je požadavek, aby na formulářích v datagridech bylo možné skrývat/zobrazovat sloupce dle výběru.
Současně toto skrytí/zobrazení musí udělat to, že SQL dotaz na databázi bude obsahovat pouze výčet sloupců dle výběru a současně data posílané na klienta budou také jen s vybranými sloupci.

Modelová situace:

  • tabulka partnerů se sloupci: id, nazev, ulice, adresa, psc
  • formulář ve WPF s datagridem a zobrazenými všemi 5 sloupci
  • vygenerovaný SQL "SELECT id, nazev, ulice, adresa, psc FROM ...."
  • uživatel si ve formu skryje sloupce id a adresa, dotaz tedy vygeneruje "SELECT nazev, ulice, psc FROM ...."

Tato vlastnost by mělá být napříč systémem. Tedy jakýkoliv form s datagridem by měl umožňovat toto dynamické skládání SQL a dynamické skládání dat (DTO).

Otázka:

  1. je toto "rozumně" realizovatelné pomocí uvedené architektury?
  2. jak by jste to řešili třeba i jiným způsobem?

Díky

odkaz
8 rmaslo
odpověděl/-a 29.6.2018
 
upravil/-a 29.6.2018

/**
Toto není odpověď na hlavní otázku v tématu,
ale jen poznámka k diskuzi s pilif, kterou
jsem potřeboval zformátovat a proto ji napsal
jako samostatný příspěvek.
**/

Jak ukládat do tabulky tak, aby šlo snadno zobrazit jak vypadala v libovolném čase její historie:
Předpokládejme, že tabulka má sloupec id, který je PK.

  1. Přidám si sloupec "platnost" (datetime), který značí od kdy je tento údaj platný.
  2. Sloupci id zruším PK.
  3. Pokud insertuji tak do "platnost" nastavím aktuální datum a čas.
  4. Neupdatuji, pokud potřebuji změnit nějaké pole v záznamu, tak tam starý záznam nechám a vytvořím nový se stejným id a aktuálním datumem+časem
  5. Pokud potřebuji vidět jak aktuálně vypadá tabulka, tak si vytvořím dotaz, který pro každé id vybere záznam s nejvyšším datumem+časem v sloupci platnost.
  6. Pokud potřebuji vědět jak tabulka vypadala v čase T tak si vytvořím dotaz, který pro každé id vybere záznam s nejvyšším datumem+časem v sloupci platnost, které je menší T. Prostě novější změny ignoruji.
  7. pokud bych potřeboval i mazat, tak ještě do db přidám nějaký sloupec "smazano" a to časové razítko v "platnost" mi říká odkdy je sloupec smazaný.

Jak to souvisí s požadavkem na stránkování "tak jak vypadalo v okamžiku zobrazení první stránky"?
a. V okamžiku zobrazení první stránky si uložím aktuální datum a čas (třeba do URL)
b. Při přechodu na další stránky už nelistuji v aktuálním stavu tabulky, ale v tom historickém, který platil v okamžiku zobrazení první stránky.

PS: Z hlediska rychlosti a snadného psaní dotazů bývá lepší si udělat dva sloupce "platnost_od" a "paltnost_do". Ale to na principu řešení celkem nic nemění, je to jen cache a rozbití nějaké normální formy.

PS2: Dělat to jen kvůli stránkování mi přijde hodně zbytečné, nicméně pokud by zadavatel na tomto systému stránkování trval tak mi to rozhodně přijde lepší než ukládání všech PK.

PS3: Často se to používá v nějakým databázích právních předpisů, kdy mě pro každý případ zajímá jak právo vypadalo v okamžiku "spáchání činu" a jaké změny přišly potom je mi jedno.

Komentáře

  • Taco : Velice inspirativní. *** Dělal jsem něco podobného ale tím, že při změně se původní hodnota odlifrovala do archivní tabulky (pomocí triggerů). Zachoval se mi tradiční způsob INSERT, UPDATE, DELETE. Jen když jsem četl nějaký historický záznam, tak jsem musel šáhnout do jiné tabulky. *** Když by si to porovnal, jaké výhody vidíš u toho tvého? 29.6.2018
  • rmaslo : @Taco: "když jsem četl nějaký historický záznam, tak jsem musel šáhnout do jiné tabulky". No otázka je jak jsi věděl "že máš číst historický záznam"? Pokud jsi to opravdu věděl třeba "z nějakého externího požadavku" tak je řešení s oddělenou tabulkou asi lepší. Pokud ovšem víš jen to, že máš vrátit stav tabulky k času T a nevíš jestli je to historie nebo aktuální stav, tak by jsi vlastně ty dvě tabulky potřeboval unionovat (a tím z nich udělat tu mojí :-) ) a nad nimi pustit nějaký filtr. A union bývá často výkonostní problém. 29.6.2018
  • Taco : @rmaslo: To je problém jen u MySQL/Maria. Třeba u postgre bych ho nečekal. Dík za postřeh. 29.6.2018

Pro zobrazení všech 9 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.