Анонс четвёртой версии redb.Core: ссылки грузятся по обращению, уникальность на любом поле, схема обновляется сама. Бесплатно, три СУБД, Free и Pro одинаково.
Готовится redb.Core 4.0. За год это первый мажор такого масштаба: не смена номера, а качественное расширение функционала. Он про три вещи, которые чаще всего просили: ленивая загрузка ссылок между объектами, уникальные ключи на любом поле и обновление схемы базы без ручных действий администратора. Всё вместе, на трёх СУБД сразу и без разделения на «в Free так, в Pro иначе».
Коротко, что изменится для приложения.
Ссылки грузятся тогда, когда их читают
Объект RedbObject<T> умеет ссылаться на другие объекты через свойства Props: заказ ссылается на клиента, клиент на менеджера, менеджер на отдел. До 4.0 один LoadAsync заказа тянул всю эту цепочку на десять уровней вглубь, а единственный способ ограничить аппетит был параметр depth, который просто обрезал ссылки в никуда.
В 4.0 ссылка на границе глубины стала ленивой: у неё есть id, схема и хеш, а Props подгружаются при первом обращении. Ровно этот объект, ровно один запрос. По смыслу это lazy-loading прокси из Entity Framework, только без динамического подкласса: тот же RedbObject<T>, у которого загружены базовые поля и подвешен загрузчик. Его собственные ссылки при этом тоже ленивые, так что ленивость транзитивна и не зависит от того, с какой глубины вы начали.
var order = await redb.LoadAsync<OrderProps>(id, depth: 1);var customer = order.Props.Customer; // ленивая ссылка: id, scheme_id, hashvar city = customer.Props.City; // первое обращение загрузило клиента, и только его
Кому нужен явный контроль, тот помечает ссылку virtual (та же конвенция, что у навигационных свойств EF) и включает EnableLazyReferences: такие ссылки остаются ленивыми на любой глубине, а WithLazyReferences(false) на конкретном запросе возвращает жадную загрузку. Коллекция ленивых ссылок дозагружается одним запросом через LoadReferencesAsync.
Сохранение родителя, вычисление хеша и сериализация в JSON ленивые ссылки не будят. Проверка этих трёх утверждений есть в тестах на каждой из шести конфигураций.
Уникальность на любом поле
Два механизма, для двух разных задач.
ValueUnique у объекта: читаемый строковый ключ (номер заказа, артикул, внешний идентификатор), уникальный в рамках схемы, с поиском по LINQ и SaveByUniqueAsync как upsert по ключу.
[RedbUnique] на поле Props: уникальность значения любого скалярного типа, включая decimal, даты и byte[], обеспеченная индексом базы. Нарушение на всех трёх СУБД поднимается одним типизированным RedbUniqueViolationException, а не тремя разными ошибками драйвера.
public class ProductProps{ [RedbUnique] public string Sku { get; set; } = ""; [RedbUnique] public byte[]? Fingerprint { get; set; }}var product = await redb.GetByUniqueAsync<ProductProps>(p => p.Sku, "SKU-1001");
База обновляется сама, а если не может, говорит об этом
4.0 ставится поверх любой базы 3.x. Схема только дополняется: новые колонки с NULL, частичные индексы, новые функции. Ничего не удаляется и не переименовывается, откат на 3.x остаётся возможным.
Обновление применяется при старте приложения. Если у роли приложения нет прав менять схему, старт останавливается типизированным RedbSchemaOutdatedException с указанием версий, а сам скрипт обновления отдаёт GetUpgradeScript() и команда redb schema --upgrade: DBA применяет его сам. Есть и режим AutoApplyDatabaseUpgrades = false для тех, кто хочет держать схему под ручным контролем всегда.
Мелочи, которые заметите
-
byte[]хранится одним BLOB, а не строкой на байт. Старая раскладка конвертируется на первой синхронизации схемы. -
Схема знает, из какого namespace её тип. Два разных
Orderиз двух проектов больше не могут молча усыновить схему друг друга. -
В SQLite хеши стали
BLOB(16), файлы старого формата конвертируются при открытии.
Что сломается
Убран старый механизм ленивой загрузки Props целиком: EnableLazyLoadingForProps, WithLazyLoading() и параметр lazyLoadProps у LoadAsync. Он делал ленивым дешёвое и жадным дорогое, жил за тремя переключателями и не имел тестов. По умолчанию он был выключен, так что проект без этих настроек ничего не заметит; в остальных достаточно удалить флаг и вызов.
Цифры и условия
Три СУБД (PostgreSQL, MSSQL, SQLite), два издания, шесть тестовых конфигураций, 2304 интеграционных теста зелёные на финальной сборке. Каждая новая проверка доказана красной на непочиненном коде.
Четвёртая версия остаётся бесплатной: Pro-возможности не требуют лицензионного ключа во всей линии 4.x, как и в 3.x. Пакеты redb, redb.Route, redb.Tsak и redb.Identity выходят одним номером.
Полный разбор с примерами на каждую возможность выйдет вместе с релизом: redb.ru/articles.
Если было полезно, ⭐ на GitHub поможет другим это найти.
Другие мои статьи — redb.ru/articles, ещё — на Хабре.
ссылка на оригинал статьи https://habr.com/ru/articles/1077124/