Шаблон репозитория - это абстракция . Его цель - уменьшить сложность и сделать остальную часть кода неосведомленной. В качестве бонуса он позволяет писать модульные тесты вместо интеграционных .
Проблема в том, что многие разработчики не понимают назначение шаблонов и создают репозитории, которые передают информацию о сохраняемости вызывающей стороне (обычно путем раскрытия IQueryable<T>
). Поступая так, они не получают выгоды от прямого использования OR / M.
Обновите, чтобы адресовать другой ответ
Кодирование для исключения
Использование репозиториев не означает возможность переключения технологии сохранения (например, изменение базы данных или использование веб-сервиса и т. Д.). Речь идет об отделении бизнес-логики от постоянства, чтобы уменьшить сложность и взаимосвязь.
Модульные тесты против интеграционных тестов
Вы не пишете модульные тесты для репозиториев. период.
Но, вводя репозитории (или любой другой уровень абстракции между устойчивостью и бизнесом), вы можете писать модульные тесты для бизнес-логики. т.е. вам не нужно беспокоиться о том, что ваши тесты не пройдут из-за неправильно настроенной базы данных.
Что касается запросов. Если вы используете LINQ, вы также должны убедиться, что ваши запросы работают, как и в случае с репозиториями. и это делается с помощью интеграционных тестов.
Разница в том, что если вы не смешали свой бизнес с операторами LINQ, вы можете быть на 100% уверены, что сбой происходит именно ваш код сохранения, а не что-то еще.
Если вы проанализируете свои тесты, вы также увидите, что они намного чище, если вы не смешиваете проблемы (например, LINQ + Business logic).
Примеры репозитория
Большинство примеров - чушь собачья. Это очень верно. Однако, если вы погуглите какой-либо шаблон дизайна, вы найдете множество дрянных примеров. Это не причина избегать использования шаблона.
Создать правильную реализацию репозитория очень просто. На самом деле вам нужно следовать только одному правилу:
Не добавляйте ничего в класс репозитория до того момента, когда вам это понадобится.
Многие программисты ленивы и пытаются создать общий репозиторий и использовать базовый класс с множеством методов, которые могут им понадобиться. ЯГНИ. Вы пишете класс репозитория один раз и храните его, пока живет приложение (может быть, годы). Зачем облажаться, будучи ленивым. Держите его в чистоте без наследования базового класса. Это упростит чтение и поддержку.
(Приведенное выше утверждение является руководством, а не законом. Базовый класс вполне может быть мотивирован. Просто подумайте, прежде чем добавлять его, чтобы добавлять его по правильным причинам)
Старье
Вывод:
Если вы не против использования операторов LINQ в своем бизнес-коде и не заботитесь о модульных тестах, я не вижу причин не использовать Entity Framework напрямую.
Обновить
Я писал как о шаблоне репозитория, так и о том, что на самом деле означает «абстракция»: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
Обновление 2
Для одного типа объекта с 20+ полями, как вы спроектируете метод запроса для поддержки любой комбинации перестановок? Вы не хотите ограничивать поиск только по имени, как насчет поиска с помощью свойств навигации, перечислить все заказы с товаром с определенным ценовым кодом, 3 уровня поиска свойств навигации. Вся причина IQueryable
изобретения заключалась в том, чтобы иметь возможность составить любую комбинацию поиска по базе данных. Теоретически все выглядит отлично, но потребность пользователя выше теории.
Опять же: объект с более чем 20 полями моделируется неправильно. Это БОЖЕСТВЕННАЯ сущность. Сломай.
Я не утверждаю, что IQueryable
это не было сделано для вопросов. Я говорю, что это не подходит для уровня абстракции, такого как шаблон репозитория, поскольку он дырявый. Не существует 100% полного поставщика LINQ To Sql (например, EF).
Все они имеют особенности реализации, например, как использовать нетерпеливую / ленивую загрузку или как выполнять операторы SQL «IN». Раскрытие IQueryable
в репозитории заставляет пользователя знать все эти вещи. Таким образом, вся попытка абстрагироваться от источника данных окончилась неудачей. Вы просто увеличиваете сложность, не получая никакой выгоды от прямого использования OR / M.
Либо правильно реализуйте шаблон репозитория, либо просто не используйте его.
(Если вы действительно хотите обрабатывать большие объекты, вы можете комбинировать шаблон репозитория с шаблоном спецификации . Это дает вам полную абстракцию, которую также можно проверить.)