Entity Framework aplikacja dwuwarstwowa czy trójwarstwowa?

0

Witam,
Aktualnie tworzę aplikację w WinForms z wykorzystaniem Entity Framework. Jednak nie umiem określić czy moja aplikacja jest dwuwarstwowa czy trójwarstwowa mianowicie na msdn znalazłem informacje że Entity Framework umożliwia tworzenie zarówno aplikacji dwuwarstwowych oraz trójwarstwowych. Wygląda to następująco:

dwuwarstwowa - Warstwa prezentacji(WPF) -> Warstwa dostępu do danych (Entity Framework)
trójwarstwowa - Warstwa prezentacji(WPF) -> Warstwa pośrednia (WCF) -> Warstwa dostępu do danych (Entity Framework)

W mojej aplikacji nie korzystam z WCF tylko WinFroms i Entity Framework.

Jednak z definicją podaną na studiach gdzie aplikacja trój warstwowa to:
Warstwa prezentacji -> Warstwa biznesowa (odpowiedzialna za przetwarzanie danych (żądań) od użytkownika. W tej warstwie realizowane są wszelkiego rodzaju funkcjonalności biznesowe) -> Warstwa danych

To wydaje mi się że Entity Framework jest właśnie tą warstwą biznesową.

Czy ktoś by mógł to wytłumaczyć ?

1

Entity Framework pozwala na tworzenie aplikacji gazylion warstwowych, bo to od Ciebie zależy, co z nim zrobisz, a bez kodu nie da się powiedzieć, co Ci wyszło.
Przy typowej implementacji EF jest używany w warstwie dostępu do danych, wrzucanie do niego logiki biznesowej nie jest zalecane.

1

EF nie jest zadna warstwą. Jesli masz wywolania ef w oknach to nie jest to 2 warstwowa aplikacja. Jesli masz jakies serwisy opakowujace komunikacja z db lub reppzytoria udostepniajace dane dla okien to mozna mowic o 2 warstwach.

0
jacek.placek napisał(a):

EF nie jest zadna warstwą. Jesli masz wywolania ef w oknach to nie jest to 2 warstwowa aplikacja. Jesli masz jakies serwisy opakowujace komunikacja z db lub reppzytoria udostepniajace dane dla okien to mozna mowic o 2 warstwach.

EF jest jak najbardziej pełnoprawną warstwą abstrakcji nad źródłem danych, inną sprawą jest czy jest wystarczającą dla danego projektu i czy nie potrzebujemy jej dalej opakować by osiągnąć jakieś wymagania poza funkcjonalne stawiane przed naszą architekturą.

2

EF nie jest warstwą tylko biblioteką ORM. Warstwę DAO możemy zaimplementować przy użyciu EF.

0

@neves: Ja to sie nie znam ale trudno chyba mowic o abstrakcji jak musisz wstawiac kod zapytania do widoku
Wszystkie where, group, orderby itp. Crudy to przeżyją ale utrzymanie takiej nawet średnią aplikacje to masakra.

3

Użycie EF czy innego ORM'a wcale nie świadczy o tym, że aplikacja jest już z automatu wielowarstwowa i spełnia założenia MVC czy MVVM, tak jak to nam wiele razy próbuje się usilnie wciskać w różnego rodzaju tutorialach. Tam wielu, zapewne "bardzo mądrych" ludzi tworzy sobie katalog o nazwie Model, w którym to trzyma sobie encje i całe to barachło z EF. Ludzie Ci wciskają swoim widzom, tudzież czytelnikom, że to właśnie jest warstwa modelu w wyżej wymienionych wzorcach i, że już mamy super zapewnioną separację. Bo wiecie... se folder utworzyli to znaczy, że kod separują, prawda? A GUZIK!

Tak zwana warstwa w aplikacji to tak naprawdę samodzielny byt, który można dołączyć np. do projektów z testami jednostkowymi i testować niezależnie od całości solucji. Posiadając osobno projekt modelu guzik powinno obchodzić Cię to co znajduje się wyżej. Model dostarcza np. interfejsy w postaci serwisów, z których korzystają warstwy wyżej. Na tym poziomie abstrakcji guzik obchodzi Cię, czy skorzysta z tego aplka webowa czy jakieś inne ustrojstwo, chociaż tutaj może trochę przesadzam, bo jakieś odgórne zalecenia zawsze są i dostosować się trzeba. ...i to jest właśnie backend, który żyje własnym życiem i dostarcza takie... hmm... "API" dla tego co będziesz chciał do tego podłączyć.

Dostarczasz również dane do wyższych warstw z takich serwisów i tutaj również NIE za pomocą gołych emcji z hinduskich tutoriali tylko wydelegowanych specjalnie do tego DTO. I naprawdę: wdrażając MVC czy MVVM nie musi być żadnych wuceefów ani czegoś tam innego. Aplikacja trójwarstwowa, która jest dobrze zrobiona posiada realnie działającą separacje tychże warstw. A co to oznacza? Ano to, że jak w takim modelu zmienisz pincet rzeczy to VM czy kontroler wyższej warstwy nawet tego nie zauważy. Powiadasz: ale tak się nie da zrobić! Da się i się robi.

Robi się:

  • interfejsując serwisy, które wystawia model;
  • używając kontenerów IoC do zarządzania serwisami, choć to tylko czubek góry lodowej;
  • korzystając z DTO czy (albo nawet i) tworząc Viewmodele;
  • korzystając z event aggregatora do komunikacji pod spodem, jeszcze bardziej separując od siebie już nawet pojedyncze viewmodele (tutaj mowa o MVVM).

Da się, da :)

PS: Ba... w MVVM wielokroć same viewmodele są interfejsowane i wsadzane jako osobny projekt do solucji :)

1
jacek.placek napisał(a):

@neves: Ja to sie nie znam ale trudno chyba mowic o abstrakcji jak musisz wstawiac kod zapytania do widoku
Wszystkie where, group, orderby itp. Crudy to przeżyją ale utrzymanie takiej nawet średnią aplikacje to masakra.

Zauważ że nie wstawiasz tego kodu w języku SQL, tylko za pomocą abstrakcyjnego obiektu zapytania(Fowler PoEE Query Object), czyli jesteś kompletnie niezależny od źródła danych które jest pod spodem. Co daje nam warstwę i abstrakcję nad źródłem danych.

Oczywiście w wielu wypadkach nie jest to wystarczające i dalej rozbudowujemy tą warstwę ...

somekind napisał(a):

EF nie jest warstwą tylko biblioteką ORM. Warstwę DAO możemy zaimplementować przy użyciu EF.

Jak już się tak czepiamy szczegółów, to DAO też nie jest warstwą ;), no ale uściślijmy :

Za pomocą EF można zaimplementować minimalną warstwę abstrakcji (DAL) nad źródłem danych bez używania żadnych dodatkowych konstrukcji takich jak DAO ;)

0

@neves: A czy to ma znaczenie w jakim języku? SQL, Linq, Criteria... Tak czy siak masz kod warstwy DAL osadzony w innej warstwie (widok, logika...) i to chyba kasuje abstrakcyjność takiego rozwiązania. A QueryObject też nie powinien raczej być stosowany warstwach innych niż DAL (okna w WinForms czy kontrolery w web). To tylko taki interpreter SQL <=> objects, żeby w czystym SQL-u nie grzebać bez potrzeby co wynika z podanego przez Cienie linka.

Projekt okienkowy WinForms nawet nie musi (nie powinien?) mieć referencji do EF bo referencje do EF mogą być w projekcie DAL. Niech się mądrzejsi wypowiedzą, czy np. brak referencji do EF w projekcie WinForms może określać ogólnie, wstępnie aplikację jako 2-warstwową.

Już pomijam użycie warstwy DAL w różnych projektach (desktop, web, mobile, api) bo czasami się tego nie potrzebuje ale jak masz kod DAL (ponownie, obojętnie w jakim języku, SQL, Linq, Criteria) w okienkach to on jest tam i nigdzie indziej. Jak to mówi Sławek Sobótka na YT, taki kod jest totalnie zakodowany.

Szczególnie w WinForms gdzie, jak ktoś nie zna lepszych rozwiązań, kusi użycie long live contextów dla okien lub nawet całej aplikacji i bindowanie wyników z EF (śledzonych) bo tak jest w tutorialach o czym pisał już @grzesiek51114. Kusi bo jest takie fajne, super szybkie ale jak to z kuszeniem, kończy się zwykle fatalnie. W super prostych CRUDach (ale takich naprawdę SUPER prostych) albo jakichś szybkich prototypach to może i ma jakiś sens ale w normalnych aplikacjach to raczej nie. Ja kiedyś coś takiego zrobiłem w dużej aplikacji i jak klient dzwoni, żeby coś zmienić czy poprawić to się zastanawiam dłuższą chwilę czy odebrać telefon :)

No i cały ten SOLID :)

0

ale w normalnych aplikacjach to raczej nie. Ja kiedyś coś takiego zrobiłem w dużej aplikacji i jak klient dzwoni, żeby coś zmienić czy poprawić to się zastanawiam dłuższą chwilę czy odebrać telefon

Sam sobie odpowiedziałeś. :) To w żadnych apkach nie ma sensu, bo a nóż zdarzy się tak, że ktoś o tym zapomni i tak już zostanie i będziecie mieli bardzo nieprzyjemnego babola do poprawiania tylekroć ilekroć coś trzeba będzie zmienić w modelu danych.

1
jacek.placek napisał(a):

@neves: A czy to ma znaczenie w jakim języku? SQL, Linq, Criteria... Tak czy siak masz kod warstwy DAL osadzony w innej warstwie (widok, logika...) i to chyba kasuje abstrakcyjność takiego rozwiązania. A QueryObject też nie powinien raczej być stosowany warstwach innych niż DAL (okna w WinForms czy kontrolery w web). To tylko taki interpreter SQL <=> objects, żeby w czystym SQL-u nie grzebać bez potrzeby co wynika z podanego przez Cienie linka.

Ma ogromne znaczenie ! Różne bazy danych używają różnych dielektów sql, zresztą entity framework może operować na dowolnym źródle danych dla którego dostarczysz mu providera (chociażby bazy w pamieci). Więc w teorii możesz podmienić żródło danych i dzięki warstwie DAL stworzonej za pomocą EF nie musisz nic zmieniać w warstwach które od niej zależą. Bo te warstwy zależne od DAL używają abstrakcyjnego języka który jest interpretowany na SQL specyficzny dla relacyjnej bazy danych, ba to nawet nie musi być SQL.
Czyli mamy warstwę -> bo dzięku EF nie uzywamy niczego co jest pod spodem niej, czyli specyficznych driverów do naszego wybranego źródla danych
Czyli mamy abstrakcję -> bo zapytania tworzymy w uogólnionym języku który jest tłumaczony na specyficzny język źródla danych

Jak dalej zauważyleś w wielu przypadkach bazowanie na samym EF nie jest dobrym pomysłem, ale to nie zmiena faktu że sam w sobie EF jest warstwą abstrakcji źródła danych i nie może tego skasować to że użycie jego samego jako DAL moze się skończyć katastrofą dla projektu :).

1
neves napisał(a):
jacek.placek napisał(a):

@neves: A czy to ma znaczenie w jakim języku? SQL, Linq, Criteria... Tak czy siak masz kod warstwy DAL osadzony w innej warstwie (widok, logika...) i to chyba kasuje abstrakcyjność takiego rozwiązania. A QueryObject też nie powinien raczej być stosowany warstwach innych niż DAL (okna w WinForms czy kontrolery w web). To tylko taki interpreter SQL <=> objects, żeby w czystym SQL-u nie grzebać bez potrzeby co wynika z podanego przez Cienie linka.

Ma ogromne znaczenie ! Różne bazy danych używają różnych dialektów sql, zresztą entity framework może operować na dowolnym źródle danych dla którego dostarczysz mu providera (chociażby bazy w pamieci).

E tam. Providery do EF też mogą być delikatnie specyficzne. Czasem np. migracje działają a czasem nie działają. Mam u siebie zapytanie Linq, które się nie wykona na niczym oprócz SQL Servera (przynajmniej w momencie pisania tamtego kodu). I prawdę mówiąc zwisa mi to, bo prawdopodobieństwo zmiany silnika bazy wynosi 0,01. Ale, oczywiście, EF zapewnia solidne, realne odcięcie od specyfiki SQL-a. Z tym nie dyskutuję.

A tak naprawdę to chyba się nie zrozumieliśmy. SQL czy jego brak to nie jest abstrakcja warstw. Abstrakcja jest wtedy kiedy widok (okno, controller, endpoint) nie ma pojęcia jak w ogóle jest realizowany dostęp do DB, a właściwie do danych bo może nawet nie być żadnej bazy. Łyżka nie istnieje.
W warstwie abstrakcyjnej możesz mieć SQL, EF, NHibernate, WCF, webapi, XML-RPC i cokolwiek innego co potrafi wysłać gdzieś lub odebrać dane (nawet jakieś wynalazki w stylu DCOM, Pipes, DDE, PPS). To jest abstrakcja a nie, ze EF odcina od SQL-a. Masz interfejs z jakiegoś repository czy serwisu i masz 5, 8, 12 metod jakoś operujących na modelach.

Więc w teorii możesz podmienić żródło danych i dzięki warstwie DAL stworzonej za pomocą EF nie musisz nic zmieniać w warstwach które od niej zależą. Bo te warstwy zależne od DAL używają abstrakcyjnego języka który jest interpretowany na SQL specyficzny dla relacyjnej bazy danych, ba to nawet nie musi być SQL.

A jak zechcę zmienić źródło danych z bazy na WCF? Mam pisać provider do WCF-a? A REST? Co z ta abstrakcją? A takie rzeczy się zdarzają. Mój bieżący case. W moim programie była baza klientów w mojej bazie danych (dostęp przez serwis z EF) a u jednego z klientów baza klientów jest w Comarch XL. EF mi raczej nie wyciągnie danych z XL-a przez jego API. Gdybym miał EF w oknach to musiałbym przepisać wszystkie okna. Jak mam dostęp do danych w serwisie wystawiającym jakiś interfejs to piszę kolejny serwis implementujący ten interfejs gadający z XL-em. Zmieniam jedną, konkretną, możliwą do przetestowania i dość prostą klasę. Podobnie z produktami, opcjami produktów, fakturami... To oczywiście specyficzny przykład ale pokazuje co to jest abstrakcja.

Czyli mamy warstwę -> bo dzięku EF nie uzywamy niczego co jest pod spodem niej, czyli specyficznych driverów do naszego wybranego źródla danych

Raczej nie. Mamy uogólniony dostęp obiektowy zamiast SQL-owego. W dawnych czasach, jak nie było ORMów to i tak z 95% (a może nawet więcej) kodu SQL-wego w typowych aplikacjach była standardowa.
Bo niby czym się różni

DbContext.Zamówienia.Where(x=>x.... == ...).GroupBy(...)

od

select * from zamówienia where ... = ... group by... ?

Taki kod przejdzie na każdej bazie.

Czyli mamy abstrakcję -> bo zapytania tworzymy w uogólnionym języku który jest tłumaczony na specyficzny język źródla danych

To nie jest abstrakcyjna warstwa dostępu do danych tylko "zobiektowanie" operacji bazodanowych. W warstwie DAL możesz mieć EF albo czystego SQL-a albo cokolwiek innego. DAL powinna enkapsulować całą logikę dotyczącą operacji na źródłach danych (cokolwiek jest źródłem, nie tylko baza danych).

Jak dalej zauważyleś w wielu przypadkach bazowanie na samym EF nie jest dobrym pomysłem, ale to nie zmiena faktu że sam w sobie EF jest warstwą abstrakcji źródła danych i nie może tego skasować to że użycie jego samego jako DAL moze się skończyć katastrofą dla projektu :).

No właśnie zmienia. Chyba inaczej rozumiemy abstrakcję źródła danych bo mi wychodzi, że w Twojej definicji to jest abstrakcja bazy danych a nie źródła, które nie musi być nawet bazą danych.
Nawet jeśli EF zwraca nie wprost modele z tabel db tylko tworzy jakieś nowe "viewmodele" to i tak masz ten kod z jednej warstwy (DAL) w innej warstwie co eliminuje enkapsulację źródła danych.

I ponownie. W super prostych CRUDach może mieć sens ale jeśli w ogóle mówimy o warstwach to niech to będą niezależne warstwy.

3
neves napisał(a):

Czyli mamy warstwę -> bo dzięku EF nie uzywamy niczego co jest pod spodem niej, czyli specyficznych driverów do naszego wybranego źródla danych
Czyli mamy abstrakcję -> bo zapytania tworzymy w uogólnionym języku który jest tłumaczony na specyficzny język źródla danych

Mamy abstrakcję (bo LINQ jest abstrakcją), nie mamy warstwy, bo ORM nie jest warstwą. Tak samo jak nie jest nią biblioteka do liczenia równań różniczkowych, logowania do pliku, czy wysyłania zapytań restowych. Biblioteki to nie są warstwy. Ogry mają warstwy, a nie biblioteki.

0

Entity Framework implementuje wzorzec repozytorium, wiec właśnie też się często zastanawiam, czy robić dodatkową warstwę czy użyć EF jako mojego repozytorium (w serwisie czy kontrolerze).

Jest to spowodowane wg. mnie trochę niepoprawną konstrukcją całego frameworka, ale w teorii myślę że można uznać EF za oddzielną warstwę (nie jak np. w przypadku NHibernate gdzie budujemy zapytania w sposób bardziej 'sqlowy' aniżeli filtrujemy kolekcję).

1
Smutny Karp napisał(a):

Entity Framework implementuje wzorzec repozytorium

Mocno przesadzone stwierdzenie, bo wzorca repozytorium na pewno nie implementuje. Po prostu context już jest jednocześnie czymś, co ludzie zwą "repozytorium generycznym" i implementują samemu.

wiec właśnie też się często zastanawiam, czy robić dodatkową warstwę czy użyć EF jako mojego repozytorium (w serwisie czy kontrolerze).

W kontrolerze to może nie, ale w serwisie jak najbardziej.

Jest to spowodowane wg. mnie trochę niepoprawną konstrukcją całego frameworka, ale w teorii myślę że można uznać EF za oddzielną warstwę (nie jak np. w przypadku NHibernate gdzie budujemy zapytania w sposób bardziej 'sqlowy' aniżeli filtrujemy kolekcję).

W NHibernate przecież też masz LINQ dostępne, więc jeśli bardzo chcesz, to możesz filtrować kolekcje tak jak w EF. Tylko to nie jest powód, aby uznawać narzędzie za warstwę.

0
somekind napisał(a):
neves napisał(a):

Czyli mamy warstwę -> bo dzięku EF nie uzywamy niczego co jest pod spodem niej, czyli specyficznych driverów do naszego wybranego źródla danych
Czyli mamy abstrakcję -> bo zapytania tworzymy w uogólnionym języku który jest tłumaczony na specyficzny język źródla danych

Mamy abstrakcję (bo LINQ jest abstrakcją), nie mamy warstwy, bo ORM nie jest warstwą. Tak samo jak nie jest nią biblioteka do liczenia równań różniczkowych, logowania do pliku, czy wysyłania zapytań restowych. Biblioteki to nie są warstwy. Ogry mają warstwy, a nie biblioteki.

Proszę, wskaż mi miejsce w którym napisałem że ORM jest warstwą, jak już wczesniej napisałem i powtórzę jeszcze raz: za pomocą EF mozemy zaimplementować minimalną warstwę DAL, a nie że EF sam w sobie jest warstwą ;).

somekind napisał(a):
Smutny Karp napisał(a):

Entity Framework implementuje wzorzec repozytorium

Mocno przesadzone stwierdzenie, bo wzorca repozytorium na pewno nie implementuje. Po prostu context już jest jednocześnie czymś, co ludzie zwą "repozytorium generycznym" i implementują samemu.

Jak najbardziej biblioteka EF używa wzorca repoztorium, jak i unit of work. Klasa DBSet implementuje wzorzec repozytorium, a DbContext implementuje wzorzec unit of work, będąc precyzyjnym ;).

1
neves napisał(a):

Proszę, wskaż mi miejsce w którym napisałem że ORM jest warstwą

Proszę: "Czyli mamy warstwę -> bo dzięku EF nie uzywamy niczego co jest pod spodem niej, czyli specyficznych driverów do naszego wybranego źródla danych"

Jak najbardziej biblioteka EF używa wzorca repoztorium, jak i unit of work. Klasa DBSet implementuje wzorzec repozytorium, a DbContext implementuje wzorzec unit of work, będąc precyzyjnym ;).

Nie, nie implementuje. Repozytorium to kontrakt dla logiki biznesowej dostarczający dostępu do operacji na aggregate rootach w formie przypominającej kolekcję, nie generyczne API dla każdego persistence modelu.

0
somekind napisał(a):

Jak najbardziej biblioteka EF używa wzorca repoztorium, jak i unit of work. Klasa DBSet implementuje wzorzec repozytorium, a DbContext implementuje wzorzec unit of work, będąc precyzyjnym ;).

Nie, nie implementuje. Repozytorium to kontrakt dla logiki biznesowej dostarczający dostępu do operacji na aggregate rootach w formie przypominającej kolekcję, nie generyczne API dla każdego persistence modelu.

Jak już wciągamy w to DDD i chcemy być precyzyjni, to repozytorium nie jest kontraktem ;) a już tym bardziej nie dla logiki biznesowej. Logika biznesowa (model domenowy) definiuje interfejs (swoje oczekiwania), za którego dostarczenie i spełnienie odpowiada warstwa infrastruktury po przez dostarczenie odpowiedniego repozytorium implementującego ten interfejs. Różnica w stosunku do tego co napisałeś jest w odwróceniu sterowania które jest wymagane w DDD. Czyli logika biznesowa definiuje kontrakt(aczkolwiek wolę słowo interfejs, bo interfejsy nie są kontraktami ponieważ nie definiują niezmienników) który spełnia repozytorium. Natomiast w kontekście DDD, DBSet nie jest dobrym repozytorium, bo nasz model domenowy musiał by zależeć od EF by go móc bezpośrednio wykorzystać, a jak wiemy nasz model domenowy nie może zależeć od bibliotek "zewnętrznych".

Ale repozytorium może istnieć również poza kontekstem DDD i wtedy jest bardzo ładnie definiowane jak dobrze wiesz przez Fowlera https://martinfowler.com/eaaCatalog/repository.html.
Konkretna implementacja DBSet<T> jak najbardziej spełnia wszystko co tam jest napisane, Kością niezgody może być definiowanie zapytań czy mają one mieć postać deklaratywną czy specyficznych metod wywoływanych z parametrami. Deklaratywne podejście jest bardziej elastyczne, wywoływanie metod daje nam większa kontrolę i porządek. Ojciec DDD Eric Evans, został zapytany który sposób konstruowania zapytań jest poprawny, i odpowiedzią było że oba są (ja osobiście preferuje nie deklaratywny).

Także DBSet<T> jest pełnoprawnym repozytorium (sam w sobie, poza kontekstem DDD) z zapytaniami definiowanymi deklaratywnie, czy to za pomocą "linq to entities" czy "entity sql", dla naszych "obiektów domenowych". Inną kompletnie sprawą jest że te "obiekty domenowe" są dalekie od ideału i nie są w pełni persistence ignorance przez pewne niedoróbki EF, ale to już inna historia ...

2
neves napisał(a):

Jak już wciągamy w to DDD i chcemy być precyzyjni, to repozytorium nie jest kontraktem ;) a już tym bardziej nie dla logiki biznesowej.

No dobrze, nie kontraktem tylko interfejsem.

Logika biznesowa (model domenowy) definiuje interfejs (swoje oczekiwania),

I to jest właśnie repozytorium - ten interfejs. Logiki biznesowej nie obchodzi jak ono zostanie zaimplementowane ani co jest źródłem danych.

Różnica w stosunku do tego co napisałeś jest w odwróceniu sterowania które jest wymagane w DDD. Czyli logika biznesowa definiuje kontrakt(aczkolwiek wolę słowo interfejs, bo interfejsy nie są kontraktami ponieważ nie definiują niezmienników) który spełnia repozytorium.

Kompletnie nie rozumiem, co tu jest różnicą. Od zawsze twierdzę, że repozytoria (te interfejsy) należą do warstwy biznesowej, bo na nich operują serwisy biznesowe, a implementacje leżą w warstwie świadomej źródła danych.

Ale repozytorium może istnieć również poza kontekstem DDD

No nie, repozytorium jest częścią DDD. Fowler w swoim tekściku się do książki o DDD odwołuje, i definiuje repozytorium tak jak ja to zrobiłem: A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection..

Ja wiem, że masa programistów uczy się z tutoriali i pisze sobie jakieś DAO, które nazywa repozytoriami i jest z siebie bardzo dumna.. ale to nie znaczy, że to są repozytoria.

Także DBSet<T> jest pełnoprawnym repozytorium z zapytaniami definiowanymi deklaratywnie, czy to za pomocą "linq to entities" czy "entity sql", dla naszych "obiektów domenowych".

Nie, bo nie jest implementacją interfejsu wymaganego przez logikę biznesową. Daje zestaw generycznych operacji do wykonywania na danych i tyle. Za to eksponuje szczegóły implementacji i pozwala na wykonywanie operacji bezsensownych z punktu widzenia biznesu. Jest "generycznym repozytorium" ze wszystkimi jego wadami.

1 użytkowników online, w tym zalogowanych: 0, gości: 1