UOW и модел на хранилище в EF5

Това е свързано с известно объркване, което имам относно част от материала за рамката на обекта, който намерих от тук: https://www.asp.net/

На тази страница се обяснява как да се обвие dbcontext с помощта на хранилище и как да се обвие хранилище с помощта на a unit of work class: http://www.asp.net/mvc/overview/older-versions/getting-стартирано-с-ef-5-using-mvc-4/имплементиране-на-хранилище-и-единица-на-работа-шаблони-в-asp-net-mvc-приложение

Въпреки това, на тази страница се посочва, че dbcontext вече е комбинация както от модела UOW, така и от модела на хранилището: https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.103).aspx

Така че, ако проблемът, който тези модели решават, вече е решен от dbcontext, защо да имплементирате повторно тези модели с EF5?

Освен това в урока класът UnitOfWork не изглежда да показва никаква полза, която UOW би трябвало да даде. например се казва: "По този начин, когато една работна единица е завършена, можете да извикате метода SaveChanges на това копие на контекста и да бъдете сигурни, че всички свързани промени ще бъдат координирани."

но всичко, което изглежда прави, е да обвива dbcontext без причина. Мисля, че пропускам нещо. Не виждам никаква координация в тази реализация... И как нещо да се "върне назад", ако нещо се обърка?


person user1809104    schedule 30.04.2015    source източник
comment
Чудя се едно и също нещо всеки път, когато видя въпроси с термините unit-of-work или repository, комбинирани с етикета entity-framework. Ще гледам това... +1   -  person spender    schedule 30.04.2015
comment
@spender да, смешно е колко много хора се опитват да добавят друг абстракционен слой върху нещо, което вече абстрахира базата данни за тях. Не вярвам, че OP в този въпрос оцени моя отговори много. И аз ще следя този въпрос с интерес.   -  person Alex    schedule 30.04.2015
comment
възможен дубликат stackoverflow.com/q/14110890/1515209   -  person qujck    schedule 30.04.2015


Отговори (4)


Не използвайте друг слой за абстракция на UoW/хранилище

Както OP правилно посочи, Entity Framework (подобно на например NHibernate и други ORMs) вече предоставя абстракция на базата данни за вас както с транзакционна „работна единица“, така и с „хранилища“, които са ви достъпни.

Допълнителният абстракционен слой UoW / хранилище е анти-модел, който трябва да се избягва на всяка цена. Има много проблеми с него, най-важните от тях са:

  • те ви пречат да използвате пълната мощност на основния ORM (мързеливо натоварване, нетърпеливо натоварване, сложни заявки, ....)
  • ако искат да осигурят някакви допълнителни предимства извън обикновения CRUD, те ще бъдат пропускливи (т.е. отразяват възможностите, присъстващи в основния ORM).

Но, но, но...

Трябва да мога да тествам модул, като се подигравам с моите хранилища

Не, нямаш. Просто използвайте база данни със съдържание, специфично за вашия тест за това. Използвайте база данни в паметта (напр. SQLite, Усилие, ...), ако искате това да е по-бързо.

EF не налага бизнес логика, която не е изразена в връзки с данни ... За да наложите този тип логика, трябва да изградите OUW/Repository/и двете от някакъв вид около контекста на EF.

Не, не трябва. Да внедрите вашата бизнес логика в абстрактен слой на инфраструктура като единица работа или хранилище е просто погрешно.

  • Ценната бизнес логика принадлежи на обекти на домейн, услуги на домейн, команди на домейн или за дълготрайни бизнес процеси, саги.
  • Обикновените валидации (т.е. не null, стойност между x и y) не: те трябва да бъдат решени в границите на вашия системен интерфейс.

Също така имайте предвид, че простите действия в стил CRUD без никаква ценна бизнес логика не трябва да преминават през всички „обръчи на слоеве“, т.е. избягвайте този модел:

  1. База данни → Обект без поведение → DTO → Преглед на модел → Изглед
  2. Редактиране на полета
  3. Изглед → Преглед на модел → DTO → Обект без поведение → База данни

Просто го заредете директно от вашия ORM във вашия контролер във формата "View Model", необходима за изгледа, и го запазете директно от вашия контролер.

На абстракции

Ненужни абстракции и обръчи на слоеве като тези са зло. Те объркат кода ви, връзват ръцете ви, изтичат, увеличават размера на кода ви и следователно количеството грешки във вашия код, без да предоставят никаква добавена стойност.

Използвайте абстракции, когато ви предлагат добавена стойност, напр. когато имате нужда от тях за решаване на междусекторни проблеми, улавяне/управление на повтарящи се модели във вашата архитектура, ...

Създаването на абстракции заради самото абстрахиране е загуба на време.

person Alex    schedule 30.04.2015

Вече писах подробно за това тук, но ще обобщя за ваша полза. Да, Entity Framework вече имплементира моделите UoW (DbContext) и хранилище (DbSet). Няма полза от повторното им прилагане отново. Всъщност има голяма вреда, тъй като значително увеличава разходите за поддръжка на вашия проект.

Защо Microsoft включи това в уводните уроци? Честно казано, не съм сигурен, но това беше грешка, която измъчваше безброй нови разработчици на MVC, включително и аз, когато едва започвах.

Има полза от някакъв вид абстракция, така че вашият проект да не зависи от нито един конкретен начин за получаване на данни. Въпреки това, тази абстракция трябва да върне конкретните данни, от които вашите действия се нуждаят, нито повече, нито по-малко. Поради липса на по-добра дума, наричам това „услуга“, въпреки че Microsoft е присадил съвсем различно значение на тази дума чрез SOA. Просто, все едно просто създавате API, който вашето приложение да използва, все едно създавате уеб API, само че изцяло базирано на код (без да се изисква действителна HTTP връзка). След това това отива във вашия DAL слой (библиотека с класове или подобен), към който вашият проект може да се позовава.

person Chris Pratt    schedule 30.04.2015

Работата с EF е, че няма бизнес логика във функционалността на OUW или Repository, която излага. Ако извикате SaveChanges, той щастливо ще запази всички промени. Въпреки това, ако има изискване при добавяне, да речем, на Widget, добавянето на Frobber за Widget е необходимо, нямате късмет (освен ако не е включена зависимост от FK). За всяка част от бизнес логиката, която не е изразена във връзки с данни, EF не я налага.

За да наложите този тип логика, трябва да изградите OUW/Repository/и двете от някакъв вид около EF контекста. Това е единствената причина да го направиш, доколкото знам.

person simon at rcl    schedule 30.04.2015

моделът на работна единица и хранилище няма отношение към рамката на обекта. това е един от модела на проектиране. така че се използва, за да направи кода ви по-четим, използваем многократно и ефективен, а също така тези модели се използват за постигане на сингелтон (еднократно създаване на обект), а също и за избягване на инверсия на контрола.

person Muddassar Hayat    schedule 30.04.2015