Pull to refresh
10
0
Send message
наружу, это один из вариантов, но это захламляет объекты, для простых свойст при сохранении в маппинге происходит обновление всех полей, тут нужно отдать должное ChangeTracker отметить измененными только те свойства, которые были изменены.
expression trees ведет к описанной проблеме
именно, мы это и делаем, и причем успешно, да на старте были затыки с архитектурными решениями, но они окупились.
1 программа, 2 бд как вы себе представляете править это независимо используя обращения к контексту?
я выше код привел, того что делаем мы
1. Формируется запрос в терминах предметной области
var query = new Query();
query.PagingOptions.SkipCount = 10;
query.PagingOptions.TakeCount = 10;
repository.Get(query);

2. Базовый Rep обрабатывает этот запрос
public virtual IEnumerable<Entity> Get( Query query )
{
	IQueryable<Entity> filtrate = _table;
	//обработка запроса
        //-----------
        ...

        filtrate = Build( filtrate, query.PagingOptions );
	return Map(filtrate);
}

3. Магический метод построения запроса
private IQueryable<Entity> Build<Q>( IQueryable<Entity> filtrate, Q query ) where Q : struct
{
	if ( !_builders.ContainsKey( typeof( Q ) ) )
		return filtrate;

	var builder = (IQueryBuilder<Entity, Q>)_builders[typeof( Q )];
	return builder.Build( filtrate, query );
}

4. Конкретный строитель запроса
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 который знает о проблемах конкретных провайдеров и борется только с ними а не с общими проблемами ОРМ.
Границы транзакции определяет UoW только он, и не кто больше.
именно пользователи это программисты
1) Сделать набор сервисов (как для внешних, только без передачи по сети), которые выставляют функции и отдают\получают данные (не объекты).

не понятно что значит данные ( не объекты ), но разве репозиторий этого не делает? он возвращает объекты предметной модели (области, слоя, как не назови)
2) Научить их работать с моделью, зашив проверку инвариантов при сохранении (DbContext.SaveChanges).
а зачем дожидаться этого самого сохранения, ведь инварианты можно проверить и раньше CodeContracts research.microsoft.com/en-us/projects/contracts проверка инвариантов это уровень домена, но как правило это забывают и не используют, тк «Да этж сколько писать? в два раза больше кода.....».
Не у всех есть администратор
Если нам нужны одни даты в UTC а другие в Local, БД должна возвращать ту дату, которая в ней храниться, а не преобразовывать
А зачем это определять?

как зачем? если система работает с несколькими провайдерами, и мы выяснили что нет возможности написать общий LINQ запрос что бы он был приемлемый для этих провайдеров.
код может иметь неожиданно разное поведение на разных БД.

если один и тот же LINQ на одном провайдере выполняется нормально, а на другом крашит приложение, то нам нужно переписать запрос под второй провайдер и только под него.

Information

Rating
Does not participate
Registered
Activity