наружу, это один из вариантов, но это захламляет объекты, для простых свойст при сохранении в маппинге происходит обновление всех полей, тут нужно отдать должное ChangeTracker отметить измененными только те свойства, которые были изменены.
public class PagingQueryBuilder<T> : IQueryBuilder<T, PagingOptions>
{
public IQueryable<T> Build( IQueryable<T> queriable, PagingOptions query )
{
var buildQuery = queriable;
if ( query.SkipCount > 0 )
buildQuery = buildQuery.Skip( query.SkipCount );
if ( query.TakeCount > 0 )
buildQuery = buildQuery.Take(query.TakeCount);
return buildQuery;
}
}
он является универсальным, можно заморочиться и распилить на 2 (но я не уверен что это нужно, хотя я могу ошибаться)
5. Конфигурация строителей
protected Dictionary<Type, object> _builders;
в базовом репозитории для типа сущности идет общая конфигурация, конкретная реализация может управлять регистрацией и чем меньши блоки запросов, тем гибче ( минус только в том что таких запросов может быть много )
Вы писали про 18 критериев фильтрации (правда походу не в этой теме, но отвечу тут, подходящие место), вам всеравно нужно будет их анализировать при построение Linq запроса, так почему же их не сгрупировать на критерии подзапросов, оформить в запрос и передать репозиторию. Или вы предпочитаете эти 18 параметров засунуть в 1 LINQ запрос? или еще хуже передать эти 18 параметров в функцию?
Гарантировать это ни как нельзя, поэтому мы и используем обертки для контроля, закрепление данных происходит только при сохранении, идет отслеживание UoWscope, по сотоянию которых ясно, нужно ли сохранять изменения или нет.
да интерфейс общий, но используется ограниченный набор запросов, отражающий запросы предметной области, и для меня важно что изменения в запросах к одной бд не поломают запросы к другим, тк переводом запросы предметной области переводятся в запросы к конкретной ОРМ, конкретной реализацией репозитория.
Во-первых, не все инварианты легко выражаются в Code Contracts.
согласен
Во-вторых, вы проверку инвариантов будете делать на каждой операции, модифицирующей состояние объекта?
по хорошему бы да, но это затратно ( хотя если просто проверять поля или свойства с простыми проверками, то это быстро )
Проверка на сохранении гарантирует, что невалидный объект не попадет в хранилище, это весьма сильная гарантия.
согласен, но как правило невалидный объект попадает в хранилище тк невалидным является объект предметной области и можно проверять его, хотя тут большой вопрос искажения объекта может быть во время маппинга, но тогда проверка объекта предметки не поможет, я наверное параноик нужно проверять и предметную область и то что может попасть в хранилище, сразу будет видно откуда у проблемы растут ноги.
Вы увидели свет в конце тоннеля, луч надежды, но не заметили что он не для вас, тк читаете между строк.
If you have a specific ORM in mind
да это так, меня очень волнует как конкретная ОРМ обрабатывает мои запросы.
Don't hide it behind an interface. It creates the illusion that you can replace one implementation with another. In practice, that's impossible.
«Не скрывайте ее за интерфейсом», да это то о чем пишу я, общий IQuariable это большая проблема. «Это создает иллюзию, что можно заменить одну реализацию другой» именно об этом я и пишу, нельзя один провайдер заменить другим и думать что это прокатит. Заметьте у меня в голове Repository который знает о проблемах конкретных провайдеров и борется только с ними а не с общими проблемами ОРМ.
1) Сделать набор сервисов (как для внешних, только без передачи по сети), которые выставляют функции и отдают\получают данные (не объекты).
не понятно что значит данные ( не объекты ), но разве репозиторий этого не делает? он возвращает объекты предметной модели (области, слоя, как не назови)
2) Научить их работать с моделью, зашив проверку инвариантов при сохранении (DbContext.SaveChanges).
а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContracts research.microsoft.com/en-us/projects/contracts проверка инвариантов это уровень домена, но как правило это забывают и не используют, тк «Да этж сколько писать? в два раза больше кода.....».
Не у всех есть администратор
Если нам нужны одни даты в UTC а другие в Local, БД должна возвращать ту дату, которая в ней храниться, а не преобразовывать
как зачем? если система работает с несколькими провайдерами, и мы выяснили что нет возможности написать общий LINQ запрос что бы он был приемлемый для этих провайдеров.
код может иметь неожиданно разное поведение на разных БД.
если один и тот же LINQ на одном провайдере выполняется нормально, а на другом крашит приложение, то нам нужно переписать запрос под второй провайдер и только под него.
2. Базовый Rep обрабатывает этот запрос
3. Магический метод построения запроса
4. Конкретный строитель запроса
он является универсальным, можно заморочиться и распилить на 2 (но я не уверен что это нужно, хотя я могу ошибаться)
5. Конфигурация строителей
в базовом репозитории для типа сущности идет общая конфигурация, конкретная реализация может управлять регистрацией и чем меньши блоки запросов, тем гибче ( минус только в том что таких запросов может быть много )
Вы писали про 18 критериев фильтрации (правда походу не в этой теме, но отвечу тут, подходящие место), вам всеравно нужно будет их анализировать при построение Linq запроса, так почему же их не сгрупировать на критерии подзапросов, оформить в запрос и передать репозиторию. Или вы предпочитаете эти 18 параметров засунуть в 1 LINQ запрос? или еще хуже передать эти 18 параметров в функцию?
по хорошему бы да, но это затратно ( хотя если просто проверять поля или свойства с простыми проверками, то это быстро )
согласен, но как правило невалидный объект попадает в хранилище тк невалидным является объект предметной области и можно проверять его, хотя тут большой вопрос искажения объекта может быть во время маппинга, но тогда проверка объекта предметки не поможет, я наверное параноик нужно проверять и предметную область и то что может попасть в хранилище, сразу будет видно откуда у проблемы растут ноги.
не понятно что значит данные ( не объекты ), но разве репозиторий этого не делает? он возвращает объекты предметной модели (области, слоя, как не назови)
а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContracts research.microsoft.com/en-us/projects/contracts проверка инвариантов это уровень домена, но как правило это забывают и не используют, тк «Да этж сколько писать? в два раза больше кода.....».
Если нам нужны одни даты в UTC а другие в Local, БД должна возвращать ту дату, которая в ней храниться, а не преобразовывать
как зачем? если система работает с несколькими провайдерами, и мы выяснили что нет возможности написать общий LINQ запрос что бы он был приемлемый для этих провайдеров.
если один и тот же LINQ на одном провайдере выполняется нормально, а на другом крашит приложение, то нам нужно переписать запрос под второй провайдер и только под него.