Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Vladek, Вы писали:
V>>Здравствуйте, gandjustas, Вы писали:
G>>>Поздравляю, вы изобрели свой IQueryable<T>, только гораздо более слабый и неудобный в использовании.
V>>Я его инкапсулировал.
G>Нет, DataFetch делает ровно тоже, что и методы OrderBy, Top, Skip, при этом не дает никаких гарантий что Top и Skip применяются при наличии OrderBy.
G>Инкапсуляция, которая не дает дополнительных гарантий потребителю не нужна от слова вообще.
Это выворачивание деталей реализации наизнанку. Не нужна вам инкапсуляция, не пользуйтесь.

Мне нужна гарантия, что репозиторий делает то, что нужно и ничего меньше
или больше, поэтому наружу торчит куцый DataFetch.
G>>>Например текстовое поле SortBy как будет работать? Там же нужно считать агрегаты по связанным таблицам, поэтому просто передать Sort в ORDER BY не выйдет. В зависимости от значения Sort надо будет генерировать разные запросы, а это не решает исходную проблему. При добавлении сценария UI — надо править репозиторий, только вы скрыли проблему из интерфейса репозиториев и спрятали её в реализацию.
V>>У меня сортировка по одному полю, поэтому этого SortBy мне достаточно. Если сортировка будет более сложной, то вместо текстовой строки я буду передавать что-то другое — зависит от условий задачи. А уж что там генерируется или делается за кулисами по этим полям, будет скрыто от внешнего мира.
G>Тогда возвращаемся к кейсу:
G>1) Показывать посты по дате добавления
G>2) Показывать посты по количеству оценок за день (самые популярные)
G>3) Показывать посты по комментов за день (самые обсуждаемые)
G>Во втором и третьем случае надо сделать join и посчитать реальное количество комментов\оценок за день. Обойтись SortBy по одному полю не выйдет.
G>Как в этом случае сделать репозитарии?
G>Кстати текстовый SortBy гораздо хуже лямбды в OrderBy.
Что такое лямбды, джойны и OrderBy? Зачем вам, пользователю репозитория, об этом знать? Может там все посты в обычном текстовом файле хранятся.
Сделаю поле вот такого типа и уже потом буду размышлять как это реализовать — через лямбды или строки.
public enum PostSortingMethod
{
Recent,
HighlyRated,
Flames
}
G>>>Также со временем ваш DataFetch распухнет, что его надежно использовать станет сложно.
V>>Любой код распухнет при бесконечном изменении и расширении требований, в реальности новые требования перестают рано или поздно поступать или наступает дедлайн.
G>У вас распухнет в двух местах: появится много классов DataFetch или в него добавится неприлично много методов, а также распухнет обработчик этого монструозного класса(ов) DataFetch.
G>Если напрямую писать Linq и использовать комбинаторы, то распухать будет только в одном месте.
В том-то и дело, что у меня Linq написан только внутри репозиториев. Чистый и конкретный, без моих лишних велосипедов и абстракций. Наследники DataFetch предназначены для передачи параметров, методов у них нет. Много классов я не боюсь, причём через некоторое время начинаешь замечать их похожесть и объединяешь их.
G>>>Предположим в том же кейсе понадобилось добавить фильтр по тегам для трех описанных выше выборок, а также добавился ее один экран, где надо показывать посты текущего пользователя (без фильтра по тегам).
G>>>Вы сделаете два разных DataFetch или будете кидать эксепшн на некорректном сочетании параметров?
V>>В данном случае, теги и авторство вполне сочетаются. А если параметры точно не будут сочетаться, то тогда сделаю два разных класса.
G>В данном случае не сочетаются. По условиям задачи. Даже если эти условия вам не нарвятся легко придумать правдоподобные условия задачи, где будут две независимые выборки, и объединить их параметры в один DataFetch не выйдет.
Ну значит будут отдельные классы входящих параметров для особых случаев, ничего страшного.