Если вы позволяете передавать Expression Tree в вашем Query, то у вас появляются те же «проблемы», которые есть у IQueryable.
это не дерево, а форма записи, простейший вариант
public static T With<T>( T target, Action<T> action )
{
action( target );
return target;
}
Не является, у вас репозитарий отдает IEnumerable. Кто помешает те же Linq методы вызвать для него?
ни кто, действительно ни кто, но вот нет запроса GetAll, есть один плюс IEnumerable будет одинаково фигово отрабатывать на больших выборках на всех бд, что сразу всплывет, если же выборка не большая, то этого ни кто не заметит, если такой запрос единичный, то наверное это не страшно ( хотя я не приветствую ). Другой сценарий при использовании paging, это как надо задать сколько элементов нужно пропустить и сколько взять, что бы после фильтрации IEnumerable осталось нужное количество объектов, ну наверное пропустить 0 взять 1000000 ( за такой запрос медаль только за храбрость и дадут ), но это случай с большими выборками ( разобрали ).
Предметно, но вот я хочу получить всех активных пользователей, я так и пишу, и ни где снаружи нет как их получить, я пишу не «как» а «что». Плюс со временем то «как» формировать запрос может измениться, добавиться свойства, удалиться, поменяться во вне изменений не будет.
это не свободный запрос, посмотрите внимательно, это всего лишь запись
query.Param = value;
query.Param1 = value1;
запрос так и остался в терминах предметной области
что такие конструкции не дублируются по всему коду?
query.Paging.Skip = 10;
query.Paging.Take = 10;
формирование запроса в терминах предметной области, не нужно делать универсальных запросов, их нужно избегать, иначе мы получим собственный IQuariable.
1) Запросы становится проще писать с репозитарием, по сравнению с IQueryable? Как то незаметно, скорее наоборот — формировать Query для репозитория гораздо более многословно, чем написать IQueryable запрос.
всегда можно использовать запись в виде Query.With(q=>q.Param = value).With…
3) Быстродействия репозиторий не прибавит, а скорее наоборот.
любая обертка ведет к потери производительности, это согласен, касательно производительности выполнения запросов, это будет зависеть только от того что написать в конкретной реализации
4) Количество изменений с репозиторием будет больше, так как репозиторий должен знать о прикладной логике приложения, чтобы хоть сколько нибудть быстро работать (нарушается принцип расслоения),
это ему знать не нужно, он должен знать о запросе в терминах предметной области и о построителе который умеет перегонять запрос в запрос к хранилищу, тк это фасад и он ничего сам не делает, только делегирует и объединяет. Вот ваше расслоение и единственность ответственности. Что касается количества изменений, да их будет больше, но любая попытка пере использования к этому ведет.
а к IQueryable дописать предикат\пейджинг\сортировку\проекцию можно прямо по месту использования, не влезая в другие слои.
да, быстро удобно, но только если у нас в приложении работа с 1 бд и только с ней, но если даже при наличии 1 бд нет ни какой гарантии что прикладной программист напишет адекватный запрос или хуже того начнет дублировать распространяя по коду (почему это плохо наверное понятно).
Прикладной программист сделал запросы сам (расширение реализации Repository) и с каждым 10-м нужно разбираться потому что он тормозит.
Я не много переписал, получил не большой прирост в цене (относительного написанного вами). С другой стороны у прикладного программиста меньше возможностей продублировать уже существующий запрос, за счет этого идет выигрыш.
Возможно, но я не думаю, что нужно иметь универсальных солдат, он и UI и DAL и еще много чего делаем, что касается доступ к разным БД, то этим явно должен заниматься человек, который в это погружен и знает ( или хотя бы догадывается ) где может возникнуть проблема.
Любое наложенное ограничение упрощает вашу жизнь, как разработчика DAL
да, а еще тестировщика, заказчика и начальства.
и усложняет жизнь программиста
да, но меньше вариантов получить по шее, за то что он по ( не знанию, лени и тд ) накосячил, за ним не до проверил тестировщик, из за этого заказчик пожаловался руководству.
Вот и весь компромис.
какой там. жесткая диктатура. Но пусть она остается в коде.
Я конечно может быть и загоняюсь, но есть Область задания функции, вы же согласны, что у разных провайдеров она разная, то есть мы может сформировать выражение так, что один провайдер сможет его обработать, а другой нет, более того можно нагородить такое, что не одному провайдеру не обработать. Я сторонник жестких ограничений, в том числе и синтаксических ( хотя это не всегда хороший подход, тк на его содержание может уйти много ресурсов ) и я плохо перевираю, когда ограничения нужно держать в голове ( других ограничителей просто нет ), а работая в команде приходиться это все держать не только в свой голове. О чем то можно забыть упустить и потом долго разбираться почему программа работает не так.
Агенты без хранения состояния, как можно меньшая область необходимой консистентности, оптимистичные сценарии обработки конкуренции, готовность к откату.
это не дерево, а форма записи, простейший вариант
ни кто, действительно ни кто, но вот нет запроса GetAll, есть один плюс IEnumerable будет одинаково фигово отрабатывать на больших выборках на всех бд, что сразу всплывет, если же выборка не большая, то этого ни кто не заметит, если такой запрос единичный, то наверное это не страшно ( хотя я не приветствую ). Другой сценарий при использовании paging, это как надо задать сколько элементов нужно пропустить и сколько взять, что бы после фильтрации IEnumerable осталось нужное количество объектов, ну наверное пропустить 0 взять 1000000 ( за такой запрос медаль только за храбрость и дадут ), но это случай с большими выборками ( разобрали ).
что в терминах хранилища на том же LINQ будет
методы-комбинаторы+generics ну да, они бесплатны, и мы не как не можем оградитьмя от дублирования путем не использования всего это го
QueryObject является ограничителем
как раз на оборот, из за того что за всеми не уследишь, репозиторий повышает контроль, правда за счет ограниченности
query.Param = value; query.Param1 = value1;
запрос так и остался в терминах предметной области
query.Paging.Skip = 10; query.Paging.Take = 10;
формирование запроса в терминах предметной области, не нужно делать универсальных запросов, их нужно избегать, иначе мы получим собственный IQuariable.
любая обертка ведет к потери производительности, это согласен, касательно производительности выполнения запросов, это будет зависеть только от того что написать в конкретной реализации
это ему знать не нужно, он должен знать о запросе в терминах предметной области и о построителе который умеет перегонять запрос в запрос к хранилищу, тк это фасад и он ничего сам не делает, только делегирует и объединяет. Вот ваше расслоение и единственность ответственности. Что касается количества изменений, да их будет больше, но любая попытка пере использования к этому ведет.
да, быстро удобно, но только если у нас в приложении работа с 1 бд и только с ней, но если даже при наличии 1 бд нет ни какой гарантии что прикладной программист напишет адекватный запрос или хуже того начнет дублировать распространяя по коду (почему это плохо наверное понятно).
мне то же уже надоело,
Я не много переписал, получил не большой прирост в цене (относительного написанного вами). С другой стороны у прикладного программиста меньше возможностей продублировать уже существующий запрос, за счет этого идет выигрыш.