дизайн интерфейса с Linq2Nibernate и IQueryable - PullRequest
2 голосов
/ 12 марта 2009

При использовании Linq2Nibernate лучше заставить ваш репозиторий возвращать IQueryable?

Насколько я понимаю, если вы используете Linq для Nibernate, запрос не будет "запущен", пока вы не вызовите .First () или Single () ect ect. Так что не лучше ли вернуть IQueryable из всех ваших интерфейсов, чтобы вы могли создавать \ манипулировать деревом выражений до его запуска?

Мои репозитории вызываются сервисами и наследуются от IServicie.

EDIT:

Во-первых, я действительно ценю все ответы. Но я хочу немного добавить к этому вопросу. Я за этот дизайн. Я не совсем понимаю оговорки в отношении тестирования. Пока процесс тестируется в каждой точке IE, в каждой точке фильтра, я не вижу особой разницы.

дополнение:

Есть ли смысл использовать Linq2Nibernate, если ваш репозиторий не возвращает IQuerrable?

Ответы [ 3 ]

3 голосов
/ 12 марта 2009

Лично я думаю, что нет. Проблема с предоставлением составных запросов из вашего репозитория заключается в том, что вы больше не можете полностью их модульно тестировать - их поведение (и успех) теперь зависит от вызывающей стороны. Например, они могут сделать .Where(x=>SomeUnmappedMethod(x)) (без перевода). Я добавил больше об этом здесь .

Если у вас есть фиксированные методы, которые возвращают (например) IList<T> или T[], то вы можете быть уверены, что если он работает в модульном тесте, он должен работать по-настоящему (за исключением ошибок конфигурации). Это также означает, что вы можете профилировать DAL изолированно и иметь разумную уверенность в том, что SQL (и т. Д.) Будет выполняться. Вы не можете профилировать / оптимизировать DAL, который изменяется в зависимости от вызывающего абонента.

(основано на моем использовании LINQ-to-SQL; конкретно не LINQ-to-NHibernate)

1 голос
/ 12 марта 2009

Это зависит от того, что потребляет ваш «Репозиторий» (цитаты из-за неоднозначности). Я бы сказал, что если что-то вроде вашего последнего уровня (UI) потребляет ваши классы репозитория на NOT , то возвращает IQueryable. Однако, если у вас есть другой уровень между вашим уровнем пользовательского интерфейса и вашим уровнем доступа к данным, я бы сказал да, вернул IQueryable и ваш средний уровень обрабатывал бы выполнение запроса.

EDIT

Что касается тестирования вашего уровня доступа к данным (DAL) / репозитория, я бы сказал, что по большей части, если у вас нет действительной логики (если есть утверждения и т. Д.), Тестов практически не будет. В этот момент вы тестируете фреймворк. Мое предложение было бы поместить другой уровень между вашим уровнем доступа (UI) и DAL, как BLL или чем-то, что обрабатывает выполнение запросов IQueryable. Таким образом, ваш репозиторий может возвращать запросы, а ваш BLL может обрабатывать их выполнение и, возможно, выполнять некоторую логику, которую затем можно протестировать.

0 голосов
/ 12 марта 2009

Я не использую IQueryable, но я бы объяснил, почему я делаю это немного иначе:

  • Проще издеваться над хранилищем, чтобы проверить другой код, который его использует
  • Интеграционные тесты - большая часть того, что вызывает запрос, находится в репозитории, поэтому я могу провести некоторые действительно сфокусированные интеграционные тесты против него
  • В связи с первым, проще проверить, что код делает соответствующие вызовы в хранилище. Это связано с тем, что вызывающий код передает информацию о фильтрах в вызов метода репозитория, а не применяет их к результатам.
...