Entity framework wspólna obsługa interfejsów modeli danych

Model

Czasami tak projektujemy naszą aplikacje, że każdy model ma jedną lub kilka cech wspólnych. Od najbardziej oczywistych, jak na przykład ID, poprzez czas i datę utworzenia, modyfikacji, czy-usunięty, czy-opublikowany i inne czy-?

W zależności od poziomu lenistwa cechy te definiowane i utrzymywane są w każdej z klas z osobna lub w jednym lub-lub w kilku interfejsach który jest implementowany przez modele.

Do momentu pisania posta byłem gościem, który posiadał jeden wspólny interface, ale właśnie teraz do mnie dotarło, że może lepiej mieć kilka interfejsów dla modeli danych, I-ID-able, I-Create-able, I-Update-able, I-cośtam-able – blogowanie rozwija!

Część wspólna

Co więcej, obsługa części wspólnej może być zaimplementowana na różne sposoby, to również zależy od poziomu lenistwa. Można to robić ręcznie w każdej metodzie repozytorium, w klasach generycznych/bazowych dla repozytoriów, można AOP, można także w klasie kontekstu. Ja aktualnie rozwiązuje to właśnie tam w samej klasie bazy danych.

Poniżej kawałek kodu:

Powyżej interfejs, który będzie wspólny dla wszystkich moich modeli. Chce znać ID (@7), kiedy został stworzony (@8) i kiedy został zaktualizowany (@9)

Klasa reprezentująca kanał rss, implementuje interfejs IModel, linie 7,8,9. Oraz inne pola ważne dla tego modelu.

Wreszcie kontekst, skupmy się nad nadpisaną metodą SaveChanges (@15) z całego chaosu wyciągam zmienione lub dodane encje, ze zawężeniem do tych które udostępniają interfejs IModel (póki co u mnie wszystkie). Następnie dla tych, które nie posiadaj ustawionej daty utworzenia ustawiam ją (@28-@31). Natomiast w przypadku daty modyfikacje, ta zostaje zawsze nadpisana (@33). W taki sposób przy każdej zmianie mam zapewnią aktualizację czasu modyfikacji, zawsze tak samo. Klasy repozytoriów nie muszą się już tym martwić.

Znowu, teraz jak patrzę na wyciąganie za chaosu; mogę osobna pobierać tylko dodane i tylko modyfikowane, w ten sposób mogę pominąć if’owanie na dacie utworzenia – <3 blog i <3 code review.

Problem rozwiązany

Nie wiem jeszcze jak to ma się do wydajności, nie wiem jak to się ma także do notracking. Wielu innych rzeczy nie wiem, wiem natomiast, że na chwilę obecną to robi mi robotę, którą wcześniej musiałem robić sam w każdym miejscu gdzie coś zmieniałem. Pomyślałem, że i wam może robić taką robotę, więc się podzieliłem.

9 thoughts on “Entity framework wspólna obsługa interfejsów modeli danych

  1. Kól, mam bardzo podobne rozwiązanie w projekcie. Jedna uwaga: sugeruję użycie UtcNow :].

  2. Pingback: dotnetomaniak.pl
  3. Ciekawe rozwiązanie. Sam jakoś nie jestem fanem Created i Updated w encjach, ale wybierając twoje rozwiązanie na pewno pisze się o wiele szybciej, nie musząc się tymi dwoma polami przejmować.

    1. Chętnie poznam innej podejście. Moje prawdopodobnie bierze się z tego, że nie jestem wielkim fanem sql i może nie wykorzystuje do końca możliwości samego silnika sql. Dawno temu, zrobiłem właśnie na encjach i działa, więc póki co jadę na tym cały czas.

  4. Ja do tego polecam jeszcze GenericRepository z metodami Update, Add, Delete które w zależności od wymagań będą ustawiały dane flagi /daty / i np id użytkownika modyfikujacego. Nie będzie trzeba tych warunków. Na koniec opcjonalnie dodać jeszcze unit of work i już będzie idealnie.

    1. Och, nienawidzę generycznych. Nie spotkałem się jeszcze z dobrym podejściem. Znowu, chętnie poznam i może zmienię zdanie. Co do samego UOW – nigdy nie rozumiałem.

    2. Przecież tu już jest generyczne repozytorium z unit of work. Nazywa się DbContext. Po co to pisać jeszcze raz?

      Żeby było idealnie, Entity Framework musiałby umieć rzucać eventy w momencie zapisu danych. Czyli może za 20 lat…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.