2013-03-28 21 views
8

Próbuję zrozumieć całą relację MVC/EF. Jeśli utworzę model encji, który będzie wchodził w interakcje z bazą danych (ponieważ nie powinieneś przekazywać ci modelu encji do widoku), wtedy klasa dla Modelu, a na końcu model widoku pokazany poniżej. Moje jedyne pytanie brzmi: zbędne jest posiadanie drugiej klasy, jedyną różnicą w przykładach, które widziałem, jest to, że stosują adnotacje danych do tej klasy, ponieważ wchodzą w interakcję z widokiem. Dlaczego tak ważne jest upewnienie się, że obiekty encji nie są eksponowane w warstwie widoku?Entity Framework i relacja z MVC

Nie zacząłem jeszcze pisać projektu, ale zakładam, że używałbyś modelu Entity do interakcji z bazą danych, a następnie wrzucisz go do ProductModelu, aby przekazać do widoku, czy to jest właściwa logika?

Entity Model:

public class Product 
{ 
    [Key()] 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public double Price { get; set; } 
} 

Model:

public class ProductModel 
{ 
    public int ID { get; set; } 
    [StringLength(50)] 
    [Required(ErrorMessage = "Product Name is required.")] 
    [Display(Name = "Product Name")] 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public double Price { get; set; } 
} 

ViewModel:

public class ProductViewModel 
{ 
    Product myProduct { get; set; }\ 
    //Plus any other properties I may need for the view. 
} 

UPDATE:

W przykład Czytałem, że mają również zestaw DBContext w następujący sposób. Czy więc klasa ProductModel jest bezużyteczna?

public class MyAppContext : DbContext 
{ 
    public MyAppContext() 
     : base("name=DBConnection") 
    { 
    } 

    public DbSet<Product> Products { get; set; } 

} 
+1

Gdzie można przeczytać, że nie należy zdać „model jednostki” do widzenia? – Floremin

Odpowiedz

1

Istnieją dwa główne powody, dla których tworzę klasę modelu, niezależnie od mojej jednostki.

  1. Jak wspomniano, atrybuty. Możesz ponownie użyć swoich jednostek w kilku aplikacjach i nie mogą używać tych samych atrybutów. Nie chcesz zanieczyszczać swoich jednostek tymi.

  2. W zależności od ORM, Twoje jednostki mogą wymagać klasy bazowej. Mogą też istnieć atrybuty lub inne dostosowania, które musisz zastosować do tych elementów. Może to spowodować trudności przy testowaniu logiki biznesowej. Dodatkowo, jeśli zmienisz ORM lub coś w swoich zmianach ORM, utrzymasz tę zmianę w izolacji od reszty aplikacji.

Zasadniczo izolujesz różne warstwy aplikacji i chronisz jedną warstwę przed zmianami wprowadzonymi w innym.

+0

Dzięki! Czy w przypadku DBContext wszystkie pozostałe warstwy są rzeczywiście przydatne? Czy to już koniec? – user2220986

+0

Prawdopodobnie nic nie zaszkodzi, aby nie mieć dodatkowych warstw, ale myślę, że to dobry pomysł. – cadrell0

+0

Wygląda na to, że mogłem pozbyć się klasy "ProductModel" i po prostu utworzyć te właściwości w viewmodelu, ale myślę, że to zależy od tego, czy ponownie użyję tej klasy produktu w kilku innych modelach widoku, czy też nie. – user2220986

1

Potrzebujesz Product class, ProductViewModel class, a następnie DbContext. Jeśli robisz to po raz pierwszy, przeczytaj Pro ASP.NET MVC 3 Framework, Third Edition

lub

Pro Asp.Net Mvc 4

Mają szczegółowe informacje o MVC i obie książki mają Real Application tutorial you can follow od początku do końca, łącznie z wdrożeniem.

Dowiesz się również o testów jednostkowych i innych narzędzi, takich jak MVC Dependency Injection (Ninject) i Min

+3

Lub przeczytaj http://www.asp.net/mvc bezpłatnie. – jrummell

-1

Dlaczego tak ważne jest, aby upewnić się, że obiekty podmiot arent wystawiony w warstwie widoku?

Nie jest. Dla prostego kontrolera CRUD często łatwiej jest po prostu przekazać obiekt encji. W przypadku bardziej złożonej strony możliwe jest współdziałanie z więcej niż jednym obiektem/typem jednostki w tym samym czasie. W jaki sposób przekażesz informacje o obu obiektach bez tworzenia nowej klasy modelu?

1

Oprócz wyżej wymienionych odpowiedzi, kolejny punkt, który nie został wymieniony, aby zapobiec wysyłaniu danych do widoku/klienta, który nie musi być.

Załóżmy na przykład, że Twój model produktu zawiera cenę, jaką płacisz dostawcy za zakup produktu. nie chcesz, aby klienci widzieli te dane, ale jeśli są uwzględnione w modelu wysłanym do widoku - nawet jeśli nie wyświetlasz tego pola - mogą je ocenić. jest to przypadek, w którym można użyć innego modelu widoku i skopiować dane z modelu ef/database do modelu widoku przed wysłaniem go do widoku.

czasami można skończyć z klasą DBcontext, EF/klasy/modelu bazy danych i kilkoma modelami podglądu, z których każdy trzyma inny podzbiór danych z modelu bazy danych.

można również znaleźć się z viewmodel, który przechowuje dane z kilku modeli bazy danych, można zobaczyć, gdy widok używa list lub rozwijanych jako alternatywę do wysyłania opcji listy w oknie.

3

Są czasy, a szczególnie na prostych modelach, gdzie model widoku może nie być wymagany. Ale i duże "ale", znalazłem bardzo nieliczne przypadki tej sytuacji i nawet wtedy, ogólnie rzecz biorąc, ogólnie znajduję potrzebę powrotu i stworzenia modelu widoku, tak czy inaczej. Posiadanie wyspecjalizowanego modelu widoku jest bezpieczniejsze, prostsze i łatwiejsze dookoła.

Możesz na to spojrzeć jako na dodatkową pracę, ale pomyśl o tym w kategoriach rozdzielenia obaw (co jest istotnym punktem MVC). Jeśli chcę przedstawić SelectList dla danych wejściowych, na przykład, mogę dodać go do ViewBag lub do mojego modelu. Jeśli dodaję go do ViewBag, tracę silne pisanie, które nigdy nie jest idealne, ale też nie należy do mojej jednostki śledzącej bazę danych. Mając model widoku, pozwól mi umieścić tę informację dokładnie tam, gdzie powinienem iść: mocno napisany model, który istnieje po to, aby obsługiwać widok i służyć tylko temu widokowi.

Lub rozważ zatwierdzenie: co, jeśli chcę pole wymagane dla bazy danych (inne niż zerowe), ale chcę uczynić to opcjonalnie dla użytkownika i wypełnić go pewną logiką biznesową za kulisami, jeśli użytkownik opts nie określać. Model widoku może łatwo poradzić sobie z tą abstrakcją, a dodanie jej do istoty samo w sobie dodałoby ogromną warstwę złożoności.

Oczywiście nic nie jest potrzebne. Możesz zawsze skonfigurować swój projekt, jak chcesz, ale najlepsze praktyki są najlepszymi praktykami z jakiegoś powodu: programiści tacy jak ty, raz po raz, natknęli się na te same problemy i skupili się wokół praktycznego rozwiązania. Możesz na jakiś czas unikać modeli widoków, ale w końcu będziesz działać na tych samych blokadach drogowych i włączać je, tak czy inaczej, po prostu rób to od samego początku i ułatw sobie życie.

0

Na początek brakuje czegoś i łączone techniki, jednym jest całkowite streszczenie DAL ze wszystkich innych warstw, to jest technika. Ale jest też inna technika, którą można zastosować; użyj klas "Jednostki" jako klas domeny. W prostym scenariuszu zawsze używamy klas domen na warstwie biznesowej, aby zastosować wszystkie reguły biznesowe. to pomoże nam bardzo połączyć testowalność poprzez warstwy i unikanie zbędnych połączeń między warstwami bez zwiększania liczby linii kodu/liczby klas.

Także to podejście, aby ten obiektów domeny (grupy Domain) bezpo¶rednio wszystkie warstwy sprawi, że rzeczy o wiele łatwiej, gdy pracuje się z MVC, ponieważ klasy mogą mieć adnotacje danych, które będą wykorzystywane przez:

  1. Odwiedzin do walidacji
  2. baza danych dla integralności

także zrozumieć koncepcję i korzystanie z tego typu zajęć jest coś, co musimy zwrócić uwagę. Jeśli używamy POCO jako naszych jednostek i klas domen, te same klasy nie są tymi samymi klasami, których Entity Framework użyje podczas interpretowania zapytań do DB. Zamiast tego EF utworzy klasy dynamiczne (pochodzące z POCO), które reprezentują ten obiekt domeny jako obiekt i ładuje wszystkie wirtualne pola, zwykle powiązane podmioty.

Będziesz zapisywać kod zajęć i trywialne ponowne mapowanie.

Nadzieja to pomaga

1

ViewModel będzie co rzeczywiście zostanie przeniesiony do/z przeglądarki, często za pomocą JSON jeśli coś, co może aktualizować w miejscu/zapisać w miejscu budowy. Więc:

  • ASP.Net MVC ma pewne ograniczenia wokół tego, co może produkować/zużywają ponad JSON (i jego ograniczenia różnią się w każdym kierunku); możesz użyć ViewModel do obejścia tego rozmiaru danych, które pobierzesz z bazy danych, może nie być to, co musi dostać się do przeglądarki - na przykład możesz potrzebować wycofać dodatkowe pola i sprawdzić je przed przekazaniem go, ale tylko chce przekazać podzbiór - ViewModel jest podzbiorem.

  • Niektóre naturalne struktury w JSON nie są tak naprawdę dostępne w bazie danych - na przykład możesz mieć odpowiednik Słownika przechowywanego w twoim Modelu, jak na przykład jedną tabelę z pewnymi wartościami i inną tabelę z FK wskazującą z powrotem do niego, identyfikator i wartość ciągu - ale aby przeglądarka mogła go wykorzystać, może być potrzebna ta wartość ciągu. Tak więc w ViewModel reprezentujesz to wszystko za pomocą prostego Dictionary (który kończy się jako prosty obiekt JS na kliencie).

  • Często takie rzeczy jak data formatowania są słabe na kliencie lub słaby przez klienta w zależności od konieczności dokładnego zegara systemowego, itp Często użyć ciągu w moim ViewModel gdzie mam DateTime w moim modelu i przełożenia od UTC do strefy czasowej i ładnie sformatuj ją na serwerze, zanim dotrze do przeglądarki.

  • Czasami należy unikać wystawiania części modelu na przeglądarkę; na przykład w niektórych systemach, jeśli wystawiłeś identyfikator wiersza przeglądarce, możesz stworzyć zagrożenie bezpieczeństwa. ViewModel sprawia, że ​​ukrywanie części modelu jest banalne.

Zobacz także: how to design ViewModel