2009-02-06 3 views
18

Я начинаю новый проект и решил попытаться включить шаблоны DDD, а также включить Linq в Entities. Когда я смотрю на ObjectContext EF, он, как представляется, выполняет функции обоих шаблонов репозитория и единицы работы:Entity Framework как репозиторий и UnitOfWork?

Репозиторий в том смысле, что базовый интерфейс уровня данных абстрагирован от представления сущности, и я могу запрашивать и сохранять данные через ObjectContext.

Единица работы в том смысле, что я могу писать все свои вставки/обновления в objectContext и выполнять их все за один снимок, когда я делаю SaveChanges().

Кажется излишним помещать еще один слой этих шаблонов поверх объекта EF ObjectContext? Также кажется, что классы Model могут быть включены непосредственно поверх генерируемых EF объектов, используя «partial class».

Я новичок в DDD, поэтому, пожалуйста, дайте мне знать, если мне что-то не хватает.

ответ

17

Я не думаю, что Entity Framework является хорошей реализацией Repository, потому что:

  • Контекст объекта недостаточно абстрактный сделать хорошее модульное тестирование вещей, которые ссылаются на него, так как он связан с доступ к БД. Наличие ссылки IRepository вместо этого работает намного лучше для создания модульных тестов.
  • Когда клиент имеет доступ к ObjectContext, клиент может делать почти все, что ему нужно. Единственный реальный контроль над этим - это сделать определенные типы или свойства частными. Трудно обеспечить надежную защиту данных таким образом.
  • В нетривиальной модели ObjectContext недостаточно абстрактен. Например, вы можете использовать обе таблицы и хранимые процедуры для одного и того же типа сущности. Вы действительно не хотите, чтобы клиент должен был различать два сопоставления.
  • В соответствующей заметке сложно написать всеобъемлющие и хорошо действующие бизнес-правила и код сущности. Действительно, является ли это даже хорошей идеей, является спорным.

С другой стороны, как только у вас есть ObjectContext, реализуя Repository паттерн тривиальна. Действительно, для случаев, которые не являются особенно сложными, репозиторий представляет собой оболочку объектов ObjectContext и Entity.

+2

Thanks Craig. Я наткнулся на какой-то код в блоге Саймона Сигала по адресу http://www.simonsegal.net/blog/2009/01/13/entity-framework-repository-specifications-and-fetching-strategies/, который предоставляет примерную реализацию репозитория образца для платформы Entity Framework. – Weej

+0

В настоящее время вы используете EntityFramework в своих проектах? Есть ли трудности в реализации? Еще раз спасибо – Weej

+0

Да, мы используем Entity Framework. В реализации Репозитория нет никаких трудностей; тривиально. У нас есть все трудности с самой платформой Entity Framework; Я думаю, что это, вероятно, верно для любой ORM. –

7

Я бы сказал, что вы должны рассматривать ObjectContext как свой UnitOfWork, а не как репозиторий.

ObjectContext не может быть хранилищем -imho-, поскольку он является «общим». Вы должны создать свои собственные репозитории, у которых есть специализированные методы (например, GetCustomersWithGoldStatus) рядом с обычными методами CRUD.

Итак, что бы я сделал, это создание репозиториев (по одному для каждого совокупного корня), и пусть эти репозитории используют ObjectContext.

+0

Спасибо за комментарии Фредерик. Не могли бы вы реализовать GetCustomersWithGoldStatus непосредственно в репозитории? Рассматривали ли вы использование методов расширения? Как вы думаете, существуют ли в этом сценарии методы расширения? – Weej

+0

На каком типе вы создали бы такой метод расширения? Я бы действительно создал его в репозитории, но не как метод расширения. Репозиторий можно рассматривать как «коллекцию», в которой вы получаете объекты, поэтому я считаю, что это действительно подходящее место для этого. –

0

Я хотел бы иметь репозиторный слой по следующим причинам:

EF Гоча

Когда вы смотрите на некоторых из существующих учебников по EF (код первой версии), то очевидно, что есть количество обработанных файлов, в частности вокруг графов объектов (объектов, содержащих объекты) и отключенных сценариев. Я думаю, что слой репозитория отлично подходит для их упаковки в одном месте.

ясная картина механизмов доступа к данным

Репозиторий дает конкретную картину о том, как BL получает доступ и обновление хранилища данных. Он раскрывает методы, которые имеют четкую цель и могут быть протестированы независимо от BL. Стандартный пример из учебников, Найти(), чтобы найти единый объект. Более конкретный пример приложения, Clear(), чтобы очистить таблицу db.

Место для оптимизаций

Неизбежно вы вышли против хитов производительности при использовании ванильного EF. Я использую хранилище, чтобы скрыть механизмы оптимизации от BL.

Примеров,

GetKeys() проект кэшированных ключей из таблиц (для принятия решений/Update Insert). Чтение ключа только быстрее и использует меньше памяти, чем чтение полного объекта.

Массовая загрузка через SqlBulkCopy. EF будет вставляться отдельными операторами SQL. Если вы хотите, чтобы один оператор вставлял несколько строк, SqlBulkCopy - хороший механизм. Репозиторий инкапсулирует это и предоставляет метаданные для SqlBulkCopy. Как и метод Insert, вам нужен метод StartBatch() и EndBatch(), который также является аргументом для уровня UnitOfWork.

Смежные вопросы