WPF + MVVM, Przechowywanie obiektów z bazy danych

WPF + MVVM, Przechowywanie obiektów z bazy danych
V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

Cześć,
Stworzyłem mały programik w ramach nauki i zastanawiam się jak go udoskonalić. Chodzi o połączenie z bazą danych i przechowywanie danych.
Program zawiera kilka widoków, w każdym z nich wykorzystuje pewną listę obiektów, które trzymam w bazie danych (lub jej część, lub dodatkowo przetwarzam te dane i dopiero wykorzystuje), wszystko z bindowanie, INotifyPropertyChanged itd. Teraz mam to zrobione tak, że w trakcie uruchomienia programu zaczytuję listę obiektów z bazy danych i przechowuję je w pamięci, w singletonie (to jest pierwszy niepewny punkt), tak abym mógł się dostać do danych bez problemu z każdego punktu programu. Nie wiem też czy dobrze jest zaczytywać wszystko na początku i operować na danych z pamięć czy za każdym razem jak chce wyświetlić listę lub jej część to mam ponownie wysyłać zapytanie do bazy danych.

gswidwa
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 lat
  • Postów:839
3

Zalezy jak duża jest Twoja baza danych. Ale chyba lepiej za każdym razem wysyłać zapytanie, wtedy masz pewność, że dane które masz w pamięci nie są różne od tych w bazie

MS
  • Rejestracja:prawie 11 lat
  • Ostatnio:około godziny
  • Postów:313
3

Teraz mam to zrobione tak, że w trakcie uruchomienia programu zaczytuję listę obiektów z bazy danych i przechowuję je w pamięci, w singletonie (to jest pierwszy niepewny punkt), tak abym mógł się dostać do danych bez problemu z każdego punktu programu. Nie wiem też czy dobrze jest zaczytywać wszystko na początku i operować na danych z pamięć czy za każdym razem jak chce wyświetlić listę lub jej część to mam ponownie wysyłać zapytanie do bazy danych.

A co jeśli w bazie będzie kilka milionów obiektów? Zaczytasz wszystkie? ;) Tak, wyślij jeszcze raz zapytanie oraz używaj stronicowania.


edytowany 2x, ostatnio: mstl
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
2

musisz do tego podejść zdroworozsądkowo - po pierwsze ile tych danych jest, po drugie jak często się one zmieniają i na ile ich "nieaktualność" ma wpływ na pracę a po trzecie jak często po nie sięgasz w programie. Jeśli są to jakieś słowniki, które generalnie uzupełnia się na raz i mają po kilkadziesiąt - kilkaset rekordów a sięgasz do nich co parę minut to możesz spokojnie raz je zaciągnąć i trzymać w pamięci. W końcu RAMu ci w komputerach dostatek :).


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
V0
A jakbym miał je trzymać w ramie, to lepiej jest trzymać w obiekcie globalnym (Singleton lub coś w tym stylu), czy tworzyć jakiś mechanizm którym przesyłałbym tą listę pomiędzy ViewModelami?
V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

No ma to sens. A co w przypadku gdy muszę najpierw przetworzyć wszystkie rekordy? Np jakbym miał produkty i musiałbym zsumować cenę całkowitą i z jakiegoś okresu i jeszcze jakąś. To lepiej jest to robić po stronie bazy? Nawet jeżeli wiązałoby się to z JOIN-ami??

I jeszcze jedno:D Jeżeli w tabeli muszę przedstawić dane z kilku tabel, to dobrym pomysłem będzie stworzenie konkretnej klasy pod tą tabele (taki model pośredni, tak jak ViewModel w ASP MVC??)

abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
1
vesper0990 napisał(a):

No ma to sens. A co w przypadku gdy muszę najpierw przetworzyć wszystkie rekordy? Np jakbym miał produkty i musiałbym zsumować cenę całkowitą i z jakiegoś okresu i jeszcze jakąś.

a co to jest cena całkowita? BTW to zależy od tego czy potrzebujesz tylko tą "cenę całkowitą" czy także poszczególne towary, które potem będziesz mocno wykorzystywał. Generalnie poza stałymi słownikami nie ma co niepotrzebnie pobierać danych "na później". W szczególności jeśli docelowo aplikacja ma mieć wielu userów to dane (jak np. sprzedaż za okres czy stan magazynowy) zmienia się na tyle szybko, że trzymanie tego w pamięci nie ma sensu

To lepiej jest to robić po stronie bazy? Nawet jeżeli wiązałoby się to z JOIN-ami??

Nie mam pojęcia co to wg Ciebie znaczy "po stronie bazy"

I jeszcze jedno:D Jeżeli w tabeli muszę przedstawić dane z kilku tabel, to dobrym pomysłem będzie stworzenie konkretnej klasy pod tą tabele (taki model pośredni, tak jak ViewModel w ASP MVC??)

To też zależy - jeśli ten "widok" będzie niezmienny (chodzi o kolumny, które chcesz pokazać) to możesz go opakować w dodatkową klasę


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
gswidwa
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 5 lat
  • Postów:839
0
vesper0990 napisał(a):

No ma to sens. A co w przypadku gdy muszę najpierw przetworzyć wszystkie rekordy? Np jakbym miał produkty i musiałbym zsumować cenę całkowitą i z jakiegoś okresu i jeszcze jakąś. To lepiej jest to robić po stronie bazy? Nawet jeżeli wiązałoby się to z JOIN-ami??

I jeszcze jedno:D Jeżeli w tabeli muszę przedstawić dane z kilku tabel, to dobrym pomysłem będzie stworzenie konkretnej klasy pod tą tabele (taki model pośredni, tak jak ViewModel w ASP MVC??)

Wtedy lepiej zrobić zapytanie pobierajace wszystkie komórki danej kolumny z danej tabeli. Ograniczasz zużycie danych

abrakadaber
abrakadaber
Pomimo przeczytania tego kilka razy nie mam pojęcia co chciałeś przekazać
gswidwa
jak chce coś policzyć to zamiast wczytywać Całą tebele z kolumnami "ID", "nazwa" itd można pobrać wszystkie komórki z kolumny "Wartość". Wszystko zamyka się w ułożeniu odpowiedniego zapytania do bazy
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
vesper0990 napisał(a):

No ma to sens. A co w przypadku gdy muszę najpierw przetworzyć wszystkie rekordy? Np jakbym miał produkty i musiałbym zsumować cenę całkowitą i z jakiegoś okresu i jeszcze jakąś. To lepiej jest to robić po stronie bazy? Nawet jeżeli wiązałoby się to z JOIN-ami??

A w czym joiny w aplikacji lepsze od tych w bazie?
Możesz to zrobić po stronie zarówno aplikacji (wysyłając odpowiedni SQL, albo definiując odpowiednią agregację w ORMie) a także po stronie bazy.
Wszystko zależy od tego, do czego to tak naprawdę potrzebujesz, czy to ma być jakiś np. raport, czy chcesz mieć te dane utrwalone, i jak często będziesz z nich korzystał.

I jeszcze jedno:D Jeżeli w tabeli muszę przedstawić dane z kilku tabel, to dobrym pomysłem będzie stworzenie konkretnej klasy pod tą tabele (taki model pośredni, tak jak ViewModel w ASP MVC??)

Używasz słowa "tabela" w jednym zdaniu w prawdopodobnie dwóch znaczeniach, co utrudnia zrozumienie pytania.

V0
Chodzi o takie dane, które zmieniają się dość często. Zrobimy coś w programie przez co doszło parę rekordów i trzeba odświeżyć jakieś wykresy np. No tak nie zauważyłem, chodziło mi żeby do jednego DataGrid wstawić dane które są zawarte w kilku tabelach w bazie danych.
somekind
Na temat wątku odpisuj w postach.
V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

Chodzi o takie dane, które zmieniają się dość często. Zrobimy coś w programie przez co doszło parę rekordów i trzeba odświeżyć jakieś wykresy np. No tak nie zauważyłem, chodziło mi żeby do jednego DataGrid wstawić dane które są zawarte w kilku tabelach w bazie danych.

mr-owl
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad rok
  • Postów:206
0

Witam,

Może powiedz ile tych danych będzie i w jakiej bazie chcesz je przechowywać? Np SQL Server pozwala na przesyłanie notyfikacji (https://www.nuget.org/packages/SqlTableDependency/). Poza tym zawsze możesz wstawić jakąś warstwę pośrednią która będzie gadała z twoim programem zwracając Ci gotowe obiekty i kolekcje a dodatkowo informowała o tym że coś się zmieniło.

Pozdrawiam,

mr-owl

edytowany 1x, ostatnio: mr-owl
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
vesper0990 napisał(a):

Chodzi o takie dane, które zmieniają się dość często. Zrobimy coś w programie przez co doszło parę rekordów i trzeba odświeżyć jakieś wykresy np.

A te wykresy mają się zmieniać w czasie rzeczywistym, czy po prostu po wejściu na odpowiedni ekran, czy może użytkownik ma mieć dostępny jakiś przycisk "odśwież"?

No tak nie zauważyłem, chodziło mi żeby do jednego DataGrid wstawić dane które są zawarte w kilku tabelach w bazie danych.

No to zrób sobie viewodel do tego DataGrida. To zresztą nawet oczywiste, że do każdego ekranu aplikacji powinieneś mieć oddzielny ViewModel.

V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

Aplikacja jest typu fiszki, gdzie użytkownik robi sobie swoje grupy słów do nauki, z serwerem online, żeby można było mieć te same słówka np na telefonie, albo innym komputerze. Ze stroną serwera nie ma problemów, wiem, że za każdym razem jak chce zobaczyć słowa na stronie to muszę odczytywać je z bazy. Ale bardziej mi chodzi o stronę desktopową albo na urządzeniu mobilnym. Rekordów może być dajmy na to 10tyś, ale każdy z rekordów może się dość często zmieniać (słowo zawiera w sobie informacje o szufladzie w której teraz się znajduje), ale tylko w określonych miejscach (tylko jak użytkownik odbędzie lekcje).

Dokładnie nie chodzi mi o mój przykład strikte (dlatego nie przedstawiałem go na początku). Chodziło mi raczej o regułę - o ile taka jest - czy lepiej jest zawsze operować na bazie, bo mamy wtedy pewność, że to są rzeczy z "pierwszej ręki" i mamy je tylko w jednym miejscu, czy raczej zaczytać dane do pamięci i operować na niej, ale martwić się o poprawny update bazy po tym jak użytkownik zmieni coś. Dodatkowym założeniem jest to, że użytkownik wymuszałby operację na danych dość często - w moim przypadku to jest z przejścia z jednego okna na drugie np: informację o wynikach na oknie powitania, okno budowania grup, okno ze słowami, okno nauki itp. Gdybym wybrał zawsze odczytywanie z bazy danych, czy to nie pogorszyłoby wydajności programu w znaczący sposób. Chodzi mi o ogólną dyskusję, niekoniecznie o konkretny przypadek

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0

No, ale nie da się ogólnie dyskutować, bo nie ma ogólnych zasad (poza takimi jak "zrób to dobrze" ;)).

Każdy użytkownik ma swoją listę słów? Czy wszystkie słowa są używane podczas jednej sesji pracy z programem?

grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
1

No to zrób sobie viewodel do tego DataGrida. To zresztą nawet oczywiste, że do każdego ekranu aplikacji powinieneś mieć oddzielny ViewModel.

Powiem więcej: nawet do zbioru kontrolek reprezentujących jeden kontekst zamiast do całego ekranu, czyli per UserConrol. No chyba, że ilość kontrolek w oknie jest nieduża, bo inaczej XAML potrafi rozrosnąć się do niebotycznych rozmiarów.

somekind
No to już w sumie zależy jak bardzo skomplikowane są ekrany.
grzesiek51114
grzesiek51114
Pewnie ale postanowiłem jednak o tym nadmienić :)
V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

Każdy użytkownik ma swoją listę słów, ale może być wielu użytkowników (oczywiście rozpatrujemy tylko jednego użytkownika i nie zaczytujemy słów innych)
W zależności czy użytkownik zrobi pewne akcje, bądź nie może się zdarzyć, że zaczytane będą wszystkie słowa, np jeżeli użytkownik wejdzie tylko w jedną lekcje będzie miał "interakcję" tylko z tymi słowami, ale jednak chcę aby na ekranie powitalnym znajdowały się takie informacje jak ilość słów które ma dany użytkownik z podziałem na to w której są szufladzie, ile ma grup, ile odbył lekcji, ile te lekcje trwały, ile trwały danego dnia, może więcej w przyszłości... Gdybym zaczytał to do pamięci to nie "rzeźbił" po bazie za każdym razem jak zostanie wyświetlone menu główne.

-przy okazji jeszcze mam pytanie czy select blokuje bazę danych? Czy mogę wykonywać wiele selectów w różnych wątkach niezależnie od siebie na tej samej tabeli?

edytowany 2x, ostatnio: vesper0990
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
vesper0990 napisał(a):

W zależności czy użytkownik zrobi pewne akcje, bądź nie może się zdarzyć, że zaczytane będą wszystkie słowa, np jeżeli użytkownik wejdzie tylko w jedną lekcje będzie miał "interakcję" tylko z tymi słowami

To ja bym odczytywał słowa dla danej lekcji do pamięci, akcje użytkownika wykonywał w pamięci, a np. przy wyjściu z lekcji czy zamknięciu aplikacji zapisał zmiany do bazy.

ale jednak chcę aby na ekranie powitalnym znajdowały się takie informacje jak ilość słów które ma dany użytkownik z podziałem na to w której są szufladzie, ile ma grup, ile odbył lekcji, ile te lekcje trwały, ile trwały danego dnia, może więcej w przyszłości... Gdybym zaczytał to do pamięci to nie "rzeźbił" po bazie za każdym razem jak zostanie wyświetlone menu główne.

To należałoby utworzyć jakąś tabelę na statystyki użytkownika, i też odczytywać ją przy otwarciu programu, a zapisywać po zakończeniu lekcji.

-przy okazji jeszcze mam pytanie czy select blokuje bazę danych? Czy mogę wykonywać wiele selectów w różnych wątkach niezależnie od siebie na tej samej tabeli?

To zależy od poziomu izolacji transakcji... no i ogólnie ma średni sens, nie masz tych danych aż tak dużo, żeby to mogło dać jakiś zysk.

V0
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 6 lat
  • Postów:47
0

Mam trzy tabele (tak w skrócie):
Group - grupy użytkownika
Word - słowa z przypisaną szufladą
Result - wyniki z lekcji - kiedy, jaki rodzaj lekcji, ile dobrych/złych odpowiedzi, jak długo trwała itp.
Aby wyświetlić wyniki muszę odczytywać dane z nich wszystkich.
Tobie chodzi o to żebym dla użytkownika stworzył tabelę gdzie w określonych kolumnach będą te dane, które chce wyświetlić na ekranie początkowym? Nie wiem czy to dobry pomysł, chociażby dlatego, że jeżeli będę chciał się dowiedzieć o wynikach z konkretnego dnia to i tak będę musiał operować na danych z tabeli Result.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)