Как стать автором
Обновить
4
0

Пользователь

Отправить сообщение

После группировки для фильтрации можно и не отходить от Query Syntax:

var filteredGroups = 
    from product in products
    join category in categories on product.CategoryId equals category.Id
    group product by category.Name into productGroup
    select new
    {
        CategoryName = productGroup.Key,
        AveragePrice = productGroup.Average(p => p.Price)
    } into s
    where s.AveragePrice > 100
    select s;

Вот я отвечал на StackOverflow: Can I reuse code for selecting a custom DTO object for a child property with EF Core?. Как на меня это самый удобный способ работать без Automapper. DelegateDecompiler так вообще упрощает это дело в разы.

Какой-то ужас при использовании асинхронности. Получается окно апдейтнут из другого потока? А что будет если после появления окна кто-то что-то нажмет и оно полезет в базу? Думаю свалится сразу.

Вам сначала надо было разобраться как работают асинки хотя бы в Dapper, а уж потом городить этот велосипед. Так вот, все начинается DbDataReader. А именно из его асинхронного метода ReadAsync. То что вы запускаете новую таску для эмуляции асинхонности, это неплохой себе выстрел в ногу.

Нужно было взять для перезаливки данных расширение linq2db.EntityFrameworkCore - там легко делается пайплайн из исходной таблицы и вставка в таргет. Вставка присходит быстро и не нужно дополнительных телодвижений.

Приблизительный пример как это могло быть:

using var sourceContext = new MyDbContext(sourceOptions);
using var targetContext = new MyDbContext(targetOptions);

targetContext.BulkCopy(sourceContext.SomeTable.AsNoTracking().AsEnumerable());
targetContext.BulkCopy(sourceContext.SomeOtherTable.AsNoTracking().AsEnumerable());
... // и тд.

Можно сделать обобщенные фукции которые могут заливать инкрементарно или перезапускать заливку если данные в таблице есть, а количество не совпадает.

Также ничего не мешает сериализировать классы в файлы и загружать их если источник недоступен.

Если честно. непонятно почему вы модель базы данных выкладываете в API. Я не верю что у вас нет навигационных свойств которые не должны попадать в API.

По нормальному надо делать DTO, в вашем случае PersonDTO

Хочется аналитику - кликхуаз, пожалуйста.

Ой что-то я сомневаюсь в текущих способностях CH, слишком молодой. Пишем для него провайдер для linq2db, ограничений пока хватает, может и поборем часть ограничений эмуляцией.

Думаю из минусов CockroachDB, все упрется в аналитические выборки. Конечно, это может и не ваш вариант, но как бы хотелось чтобы база и считала быстро.

Стоит также посмотреть и сюда https://www.singlestore.com. Такой же непотопляемый черт, петабайт ready, но с чертовски скоростной аналитикой. Платный однако. Накормить его данными можно кучей способов и очень быстро.

Вот вам общий туториал, наверное лучшее что я видел (тыкать по сценариям использования)

https://tortugaresearch.github.io/DotNet-ORM-Cookbook/ORMs.htm

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

Вот я так и тестирую запросы во время исполнения. Так как разбираю запрос на маленькие и каждую часть спокойно могу проверить на правильность выборки.

Если уж вы ищите легковесные ORM, то не проходите мимо linq2db. LINQ превращает все что вы тут сгенерили в легкую прогулку. LINQ запро на копирование, удаление тоже возможен.

И тут вы опять попадете в Parameter Sniffing. Тут надо или инлайнить параметры или добавлять к запросу OPTION(...).

Не забываем и NewSQL базы. Очень впечатлил SingleStore (бывший MemSQL). Когда PG начал тупить, пришлось попробовать альтернативы. И я был приятно удивлен скоростью трехэтажных запросов, где PG просто заставлял идти делать чай между попытками заставить его паралелить запросы, ведь ему дали 40 ядер, а он использует одно.

Тем не менее использование транзакционной СУБД в качестве OLAP хранилища всегда будет считаться архитектурной недоработкой

Kaгбы SingleStore (бывший MemSQL) с вами не согласен. Да там тоже есть колоночное хранилище, но и табличное также. Запросы быстры как молния, а time series прикручен как само собой разумеющееся.

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

Ну я бы ваш запрос переписал как-то так:

SELECT HR.*
FROM 
	(
		SELECT 
			HRX.*,
			ROW_NUMBER () OVER ( ORDER BY HRX.PROCESS_DATE DESC) AS RN
		FROM SOME_TABLE HRX 
	) HR
JOIN SOME_TABLE2 AD ON AD.ID = HR.ADDRESS_ID
JOIN SOME_TABLE_3 CH ON AD.ID = CH.ADDRESS_B_ID AND CH.ID = 517425
WHERE HR.RN = 1
	AND ….	

Для .NET стека просто толпень инструметов, хотя бы погуглили. Microsoft Orleans заслуживает особого внимания.

EF Core хвалят те у кого база просто маленькая. На реальных данных они незаметно переходят на хранимки. Скорость генерации сложного запроса в EF Core просто отстойная. Им приходится перелопачивать код чтобы упростить свои визиторы чтобы итерации не гоняли ту же песню миллионы раз.
Об оконных функциях тоже можно забыть. Parameters Sniffing возможен и никак не обходится. DML операции спрятаны через ChangeTracker — еще тот прикол подтянуть 1000 записей чтобы у них поменять одно поле.


Если уж сравнивать SQLAlchemy с .NET ORM, то только с linq2db, он не прячет от вас SQL и быстр как молния. Также он сам проводит оптимизацию запросов вплоть до того что может поотбрасывать незначимые JOIN.

Да сравнивать их незачем, разве что по производительности. Внезапно база данных это не набор объектов и если ее так трактовать то имеем то что имеем — через год-полтора в высоконагруженных системах половина кода уходит в хранимки, сущности "аттачатся" для апдейта, удаления, покупаются Zzzz библиотеки. Остается только то что перевести в SQL сил и денег нет.

Если для запроса нужна хранимка на 1000 строк, то в LINQ это будет выглядеть еще ужасней

Ох уж эти теоретики. Ужасен SQL который сложно отдебажить. А LINQ просто разбиваешь на подзапросы, тестируешь их отдельно и объединяешь. И, как показывает практика, часто самая лучшая реализация хранимки по быстродействию — это, черт побери, склейка строк.


К тому же для (снова подчеркну это) именно "отчетных" запросов, т.е. OLAP-задач, по-хорошему должна использоваться отдельная БД со своей схемой

Отчетные, не отчетные. В чем разница? ANSI-SQL никто не отменял. Если LINQ провайдер строит ожидаемый SQL — хоть все процедуры выбрасывай. Да и что тут такого что у них может быть своя схема? (давайте остановимся на реляционках, а то тут можно и до эксцелек дойти)

SQL уступает в том что на нем сложно переиспользовать части кода. Вот тут LINQ рвет его как тузик грелку. Хочешь делать эффективные SQL запросы — делай копипасту.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность