MVVM + EF czy dobrze?

MVVM + EF czy dobrze?
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Witajcie,

jak co niektórzy wiedzą uczę się Entity Framework i chcę go dobrze zastosować wespół z MVVM.

Teraz chcę się zapytać czy moje podejście jest dobre?

Wołam @DibbyDum i innych mvvm'owców.

PS: Wiem, że EF jest jaki jest ale mimo wszystko chcę go poznać. Później równolegle sobie może nHibernate zrobię.

edytowany 3x, ostatnio: grzesiek51114
DibbyDum
@fasadin jako człowiek pracujący na co dzień na pewno też coś dorzuci od siebie. :)
fasadin
niestety nie pracuje z EF. Jedynie do czego moglbym sie przyczepic to formatowanie w FindBook (nie podoba mi sie jak rozrozniasz if/else + linq wole rozdrabniac jezeli jest bardziej skomplikowane. Na pierwrzy rzut oka wyglada ok, ale nie wime jak sie z EF pracuje
T2
  • Rejestracja:prawie 11 lat
  • Ostatnio:8 miesięcy
  • Postów:194
1

Odnośnie ViewModelu:

  • Usuń magic stringi z property change
  • Operacje wyszukiwania oraz dodawania przesuń do osobnej klasy. Natomiast w ViewModelu używaj słabej referencji do tej klasy (Interfejsu). Zapewni to tobie większą możliwość testowania.
  • Uwaga od mnie ja bym przeniósł definicje akcji do osobnych method. Ułatwi to potem np. wprowadzenie Controllera.
edytowany 1x, ostatnio: teo215
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
3

Słowem wstępu MVVM to wzorzec architektury dzielący ogólnikowo aplikacje na trzy warstwy odseparowane od siebie.

  1. View odpowiada za GUI, czyli za wygląd formatek za wszelakie wodotryski czy to napisane w XAML czy w c# code-behind bez różnicy.
  2. ViewModel tutaj leci logika aplikacji, głownie odpowiedzialna za pobierz dane z Model przekaż do View i z powrotem.
  3. Model tutaj powinna być logika biznesowa (domena), serwisy, repozytoria i inne szmery bajer które korzystają na przykład z bazy danych za pośrednictwem EF.

A więc wracając do twojego kodu:

  1. Wywalić z ViewModel ten "DbContext" i ubrać to w jakieś serwisy po stronie modelu.
  2. Model to nie mapowanie tabelki z bazy danych.
  3. "DbContext" jak "DbContext" jest okej nie ma co się nad nim zastanawiać.

View, ViewModel i Model to ogólniki pod nimi zawsze kryją się bardziej szczegółowe wzorce i implementacje.

P.S. nie przepracowałem ani pół sekundy jako WPF/MVVM developer więc równie dobrze mogę pieprzyć głupoty. :)


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 2x, ostatnio: DibbyDum
0

To dopiero początek przygody z MVVM, pamiętam jak kląłem kiedy coś mi nie działało, MVVM jest "magiczne" :D

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

Dzięki wszystkim za feedback. No ja juz próbuję mvvm używać dobre dwa latka :) Ciągle dowiaduję się czegoś nowego :)

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

@DibbyDum, @teo215 Czy chodziło o taki serwis?

Kopiuj
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Library.Model;

namespace Library.Services {
    public interface ILibraryService {
        ICollection<Book> GetBooks();
        ICollection<Author> GetAuthors();
        ICollection<BooksView> GetBooksView();

        bool InsertBook(Book book);
        bool InsertAuthor(Author author);
        bool Associate(int bookId, int authorId);
    }

    public class LibraryService : ILibraryService {
        public ICollection<Book> GetBooks() {
            using (var db = new LibraryContext()) {
                return db.Books.ToList();
            }
        }

        public ICollection<Author> GetAuthors() {
            using (var db = new LibraryContext()) {
                return db.Authors.ToList();
            }
        }

        public ICollection<BooksView> GetBooksView() {
            using (var db = new LibraryContext()) {
                return db.BooksView.ToList();
            }
        }

        public bool InsertBook(Book book) {
            try {
                using (var db = new LibraryContext()) {
                    db.Books.Add(book);
                    return db.SaveChanges() > 0;
                }
            }
            catch (Exception) {
                return false;
            }
        }

        public bool InsertAuthor(Author author) {
            try {
                using (var db = new LibraryContext()) {
                    db.Authors.Add(author);
                    return db.SaveChanges() > 0;
                }
            }
            catch (Exception) {
                return false;
            }
        }

        public bool Associate(int bookId, int authorId) {
            try {
                using (var db = new LibraryContext()) {
                    var book = db.Books.Single(b => b.Id == bookId);
                    var author = db.Authors.Single(a => a.Id == authorId);

                    book.Authors.Add(author);
                    author.Books.Add(book);

                    return db.SaveChanges() > 0;
                }
            }
            catch (Exception ex) {
                System.Windows.MessageBox.Show(ex.ToString());
                return false;
            }
        }
    }
}

Generalnie baza jest prosta. Taka tam... żeby ogarnąć działanie ORM:

61883b86f2.png

Klasy Book i Author to fizyczne tabele w bazie danych. Klasa BookView to klasa, która bierze dane z widoku zrobionego w bazie.
Czy chodziło o takie (albo podobne) podejście? :)

PS: Nie zwracajcie uwagi na ogolny Exception i to, że jest tam tylko return false. Chodzi generalnie o ideę serwisu. W viewmodelu będzie luźna referencja w postaci interfejsu.

edytowany 2x, ostatnio: grzesiek51114
DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
1

Koncepcja jest ogólnie słuszna tylko zamiast ObservableCollection zwracał bym IList.


Yubby dibby dibby dibby dibby dibby dibby dum..
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

@DibbyDum, @teo215 robicie jeden duży serwis czy dzielicie serwis per tabela? A może jeszcze inaczej? Pytam, bo jak tych tabel jest dużo w bazie to per tabela porobi się mnóstwo serwisów.

DibbyDum
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Polska, Kraków
2

Wiele serwisów, ale nie per tabela tylko per logika biznesowa, takie SRP biznesowe. :D


Yubby dibby dibby dibby dibby dibby dibby dum..
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Czyli tak jak się w sumie domyślałem. :) I te serwisy plus to co jest z ORM'a to właśnie nasz model. :)

edytowany 1x, ostatnio: grzesiek51114
T2
  • Rejestracja:prawie 11 lat
  • Ostatnio:8 miesięcy
  • Postów:194
3

Również podpisuję się pod słowami @DibbyDum
Serwis powinien zwracać IList.Serwis powinien zawierać logikę biznesową a nie operować na pojedynczych tabelach (Wtedy był by tylko nakładą na EF).
Zazwyczaj tworzę kilka mniejszych serwisów gdzie każdy z nich jest odpowiedzialny za konkretną cześć logiki biznesowej.

  • Skoro już masz luźne wiązanie śmiało możesz wstrzyknąć tą zależność za pomocą konstruktora abyś nie tworzył instancji w ramach ViewModelu.
  • Ja jeszcze tworze sobie Interfejs dla ViewModelu. Wykorzystuje ten interfejs w widoku w ramach DesignInstance. Ułatwia mi to tworzenie kodu.
edytowany 1x, ostatnio: teo215
grzesiek51114
grzesiek51114
Wtedy był by tylko nakładą na EF hehe kiedyś zapętliłem się z Viewmodelem tak, że przesyłałem do niego kontrolki, przez co zrobiła się z tego nakładka na code-behind. Szybko się pokapowałem, że coś jest nie tak ale śmiesznie to wyglądało :)
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0
teo215 napisał(a):
  • Skoro już masz luźne wiązanie śmiało możesz wstrzyknąć tą zależność za pomocą konstruktora abyś nie tworzył instancji w ramach ViewModelu.

Rozwiń jak możesz. Teraz mam właśnie instancję, nazwijmy to IService w VM.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.