Zastanawiam się, ponieważ jeśli tak, to dlaczego Entity Framework nie oferuje logiki tworzenia nowego obiektu o tych samych właściwościach do przesyłania danych między warstwami?
Korzystam z obiektów encji, które generuję za pomocą frameworku encji.
design
design-patterns
architecture
domain-driven-design
entity-framework
użytkownik2484998
źródło
źródło
Odpowiedzi:
To zależy od Ciebie.
Większość ludzi powie ci, że nie jest to dobra praktyka, ale w niektórych przypadkach możesz jej uniknąć.
EF nigdy nie grał dobrze z DDD z wielu powodów, ale dwa wyróżniają się: nie można sparametryzować konstruktorów na swoich bytach i nie można enkapsulować kolekcji. DDD polega na tym, ponieważ model domeny powinien obejmować zarówno dane, jak i zachowanie.
W pewnym sensie EF zmusza cię do posiadania anemicznego modelu domeny, w tym przypadku możesz użyć encji jako DTO. Możesz napotkać pewne problemy, jeśli korzystasz z właściwości nawigacji, ale możesz szeregować te podmioty i wysyłać je przewodowo. Może to nie być praktyczne. Będziesz musiał kontrolować serializację dla każdego elementu, który ma właściwości, których nie musisz przesyłać. Łatwiejszym sposobem jest zaprojektowanie oddzielnych klas dostosowanych do przesyłania danych. W tym celu tworzone są biblioteki takie jak AutoMapper .
Na przykład: Załóżmy, że masz klasę wywoływaną
Person
z następującą definicją:Zakładając, że chcesz gdzieś wyświetlić listę pracowników, może być praktyczne wysłanie tylko
Id
,FirstName
iLastName
. Ale musisz przesłać wszystkie inne nieistotne właściwości. To nie jest duży problem, jeśli nie zależy ci na wielkości odpowiedzi, ale ogólną ideą jest wysyłanie tylko odpowiednich danych. Z drugiej strony możesz zaprojektować interfejs API, który zwraca listę osób, w takim przypadku może być konieczne przesłanie wszystkich właściwości, co ma sens w przypadku serializacji i wysyłania jednostek. W takim przypadku utworzenie klasy DTO jest dyskusyjne. Niektórzy ludzie lubią mieszać byty i DTO, inni nie.Aby odpowiedzieć na zaktualizowane pytanie, EF jest ORM. Jego zadaniem jest mapowanie rekordów bazy danych na obiekty i odwrotnie. To, co robisz z tymi obiektami przed i po przejściu przez EF, nie jest częścią jego obaw. Nie powinno tak być.
źródło
As of EF Core 2.1, only services known by EF Core can be injected. Support for injecting application services is being considered for a future release.
Bardzo lubię, aby usługi aplikacyjne były wstrzykiwane moim podmiotom.Nie, nie jest.
Idealnie, DTO będą pasować do twoich repozytoriów trwałości (aka, twoich tabel bazy danych).
Ale twoje klasy biznesowe niekoniecznie są do siebie dopasowane. Możesz potrzebować dodatkowych klas lub klas oddzielonych lub połączonych z tym, co masz w bazie danych. Jeśli twoja aplikacja jest mała, możesz nie widzieć tego rodzaju problemów, ale w średnich i dużych aplikacjach zdarza się to często.
Inną rzeczą jest to, że DTO należą do dziedziny, która dotyczy uporczywości, podczas gdy Twoja warstwa biznesowa nie powinna o nich nic wiedzieć.
źródło
To właściwie bardzo zły pomysł. Martin Fowler ma artykuł o lokalnych DTO .
Krótko mówiąc,
DTO
wzorzec był używany do przesyłania danych poza procesem, na przykład przez drut, a nie między warstwami w tym samym procesie.źródło
Nie, to zła praktyka.
Pewne powody:
@JsonIgnore
Ze świata Java), ale prowadzi to do następnego problemu ...get
metodę encji.Tak więc łatwiej i bezpieczniej jest użyć jakiegoś narzędzia mapującego, które pomoże ci w tym zadaniu, mapując pola encji na Dto.
źródło
Aby zakończyć to, co powiedział @Dherik, głównymi problemami związanymi z używaniem obiektów bytu jako obiektów do przesyłania danych są:
W transakcji podejmujesz ryzyko zatwierdzenia zmian dokonanych w Twojej jednostce, ponieważ używasz jej jako DTO (nawet jeśli możesz odłączyć jednostkę sesji w transakcji, przez większość czasu musisz sprawdzić ten stan przed wszelkie modyfikacje Twojej jednostki-DTO i upewnij się, że nie bierzesz udziału w transakcji lub że sesja została zamknięta, jeśli nie chcesz, aby zmiany były utrwalane).
Rozmiar danych, które udostępniasz między klientem a serwerem: czasami nie chcesz wysyłać całej treści encji do klienta, aby zminimalizować rozmiar odpowiedzi żądania. Oddzielenie DTO od encji jest bardziej elastyczne, aby specjalizować dane, które chcesz wysłać w określonych przypadkach użycia.
Widoczność i konserwacja: Musisz zarządzać adnotacjami jpa / hibernacjami na polach swojej encji i utrzymywać adnotacje Jacksona, aby serializować w jsonie w tym samym miejscu (nawet jeśli możesz oddzielić je od implementacji encji, umieszczając je w interfejsie dziedziczonym przez jednostka). Następnie, jeśli zmienisz treść DTO podczas dodawania nowego pola, inna osoba prawdopodobnie może pomyśleć, że jest to pole encji, a zatem pole danej tabeli w bazie danych (nawet jeśli możesz użyć
@Transient
adnotacji na wszystkich polach DTO w tym przypadku ...!).Moim zdaniem powoduje hałas podczas czytania encji, ale moja opinia jest z pewnością subiektywna.
źródło