2009-02-06 9 views
18

Zaczynam nowy projekt i postanowiłem spróbować włączyć wzorce DDD, a także włączyć Linq do Entities. Kiedy patrzę na ObjectContext EF, wydaje się, że wykonuję funkcje zarówno repozytorium jak i Unit of Work:Entity Framework jako repozytorium i UnitOfWork?

Repozytorium w tym sensie, że bazowy interfejs poziomu danych jest pobierany z reprezentacji encji i mogę żądać i zapisywać dane poprzez ObjectContext.

Unit of Work w tym sensie, że mogę napisać wszystkie moje inserty/aktualizacje do objectContext i wykonać je wszystkie za jednym razem, gdy zrobię SaveChanges().

Wydaje się zbędne umieszczanie kolejnej warstwy tych wzorów na wierzchu EF ObjectContext? Wydaje się również, że klasy Model mogą być wbudowane bezpośrednio na elementach generowanych przez EF przy użyciu "klasy częściowej".

Jestem nowy w DDD, więc proszę dać mi znać, jeśli czegoś tu brakuje.

Odpowiedz

17

Nie sądzę, że Entity Framework jest dobra implementacja repozytorium, ponieważ:

  • Kontekst obiekt jest niewystarczająco streszczenie zrobić dobre testy jednostkowe rzeczy, które ją odniesienia, ponieważ jest on zobowiązany do dostęp do DB. Posiadanie referencji IRepository działa znacznie lepiej, tworząc testy jednostkowe.
  • Gdy klient ma dostęp do ObjectContext, klient może zrobić prawie wszystko, na czym mu zależy. Jedyną prawdziwą kontrolą nad tym jest to, aby pewne typy lub właściwości były prywatne. W ten sposób trudno jest wdrożyć dobre zabezpieczenie danych.
  • W niebanalnym modelu, ObjectContext jest niewystarczająco abstrakcyjny. Można na przykład mieć tabele i procedury składowane odwzorowane na ten sam typ jednostki. Naprawdę nie chcesz, aby klient rozróżniał dwa odwzorowania.
  • W powiązanej notatce trudno jest napisać kompleksowe i dobrze egzekwowane reguły biznesowe i kod jednostki. Rzeczywiście, to, czy jest to nawet dobry pomysł, jest dyskusyjne.

Z drugiej strony,, gdy już masz obiektowy kontekst, implementacja wzorca repozytorium jest banalna. Rzeczywiście, w przypadkach, które nie są szczególnie skomplikowane, Repozytorium jest czymś w rodzaju wrappera wokół ObjectContext i typów Entity.

+2

Dzięki Craig. Na blogu Simona Segala natknąłem się na http://www.simonsegal.net/blog/2009/01/13/entity-framework-repository-specifications-and-fetching-strategies/, który zawiera przykładową implementację repozytorium dla Entity Framework. – Weej

+0

Czy obecnie używasz EntityFramework w swoich projektach? Czy są jakieś trudności w implementacji? Jeszcze raz dziękuję – Weej

+0

Tak, używamy Entity Framework. Nie ma trudności w implementacji Repozytorium; jest trywialne. Mamy wiele problemów z samym Entity Framework; Myślę, że jest to prawdą w przypadku każdej ORM. –

7

Powiedziałbym, że powinieneś spojrzeć na ObjectContext jako UnitOfWork, a nie jako repozytorium.

Obiekt ObjectContext nie może być repozytorium - ponieważ jest "ogólny". Powinieneś utworzyć własne repozytoria, które mają specjalistyczne metody (na przykład GetCustomersWithGoldStatus) obok zwykłych metod CRUD.

Więc, co bym zrobił, to stwórz repozytorium (po jednym dla każdego root-roota) i pozwól tym repozytoriom korzystać z ObjectContext.

+0

Dzięki za komentarze Frederik. Czy zaimplementujesz GetCustomersWithGoldStatus bezpośrednio w repozytorium? Czy rozważałeś zastosowanie metod Extension? Czy sądzisz, że w tym scenariuszu istnieją metody rozszerzania? – Weej

+0

Na jakim typie zostałaby stworzona taka metoda rozszerzenia? Naprawdę chciałbym utworzyć go w repozytorium, ale nie jako metodę rozszerzenia. Repozytorium można uznać za "kolekcję", z której pozyskuje się podmioty, więc uważam, że jest to prawidłowe miejsce, w którym można to zrobić w ten sposób –

0

Lubię mieć repozytorium warstwę z następujących powodów:

EF haczyka na

Jeśli spojrzeć na niektóre z obecnych tutoriali na EF (kod pierwszej wersji), to jest oczywiste, że jest to liczba gotcha do obsługi, szczególnie wokół wykresów obiektów (encji zawierających podmioty) i scenariuszy odłączonych. Myślę, że warstwa repozytorium świetnie nadaje się do owijania ich w jednym miejscu.

Wyraźny obraz mechanizmów dostępu do danych

Repozytorium daje konkretny obraz tego, w jaki sposób BL korzysta i aktualizowanie przechowywania danych. Ujawnia metody, które mają jednoznaczny cel i mogą być testowane niezależnie od BL. Standardowy przykład z podręczników, Znajdź(), aby znaleźć pojedynczy obiekt. Więcej specyficznego dla aplikacji przykładu, Wyczyść(), aby wyczyścić tabelę db.

Miejsce na optymalizacje

Nieuchronnie wymyślić przeciwko trafień wydajności podczas korzystania z wanilii EF. Używam repozytorium, aby ukryć mechanizmy optymalizacji przed BL.

przykładach

GetKeys() do projekcji w pamięci podręcznej kluczy w tabelach (pod wkładkę decyzji/update). Odczyt tylko klucza jest szybszy i zużywa mniej pamięci niż czytanie całego obiektu.

Ładowanie zbiorcze za pośrednictwem SqlBulkCopy. EF wstawi poszczególne instrukcje SQL. Jeśli chcesz, aby pojedyncza instrukcja wstawiała wiele wierszy, SqlBulkCopy jest dobrym mechanizmem. Repozytorium to hermetyzuje i dostarcza metadane dla SqlBulkCopy. Oprócz metody Insert potrzebna jest metoda StartBatch() i EndBatch(), która jest również argumentem dla warstwy UnitOfWork.