Полезные функции EF Core 8. Окончание
Начало
3. Столбцы JSON
Сопоставление столбцов JSON уже было частью EF Core 7, поэтому оно не совсем новое, но есть некоторые улучшения. Предположим, мы создаём некий код авторизации с настраиваемыми ролями и политиками:
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public IList<CustomPolicy>
Policies { get; set; };
}
public class CustomPolicy
{
public string Key { get; set; }
public bool Value { get; set; }
}
Чтобы сопоставить эти сущности с одной таблицей, а Policies - с одним столбцом, конфигурация будет такой:
public void Configure(EntityTypeBuilder<Role> b)
{
b.ToTable("Roles");
b.HasKey(o => o.Id);
…
b.OwnsMany(o => o.Policies, x =>
{
x.Property(p => p.Key);
x.Property(p => p.Value);
x.ToJson();
});
}
При создании таблицы свойство Policies будет текстовым столбцом, содержащим JSON. Это было и в EF Core 7. В 8й версии поддерживаются запросы с использованием индексов массивов JSON, трансляция запросов к коллекциям JSON, содержащим сложные типы, запросы и обновления отдельных полей JSON. Также JSON колонки доступны в SQLite.
4. Контрольные значения
Контрольное значение заставляет EF Core проверять заданное значение вместо значения по умолчанию типа для свойства, которое необходимо установить. Предположим, что мы моделируем сущность ToDoItem:
public class ToDoItem
{
public int Id { get; set; }
public string Name { get; set; }
public int Priority { get; set; }
}
По бизнес-правилам приоритет по умолчанию должен быть 100:
public void Configure(EntityTypeBuilder<ToDoItem> b)
{
b.ToTable("ToDoItems");
b.HasKey(o => o.Id);
…
b.Property(o => o.Priority)
.HasDefaultValueSql(100);
}
Т.к. свойство Priority не обнуляемое, а значение по умолчанию для int равно 0, у нас не будет возможности сохранить экземпляр ToDoItem со значением 0. EF Core идентифицировал бы 0 как значение по умолчанию, предположил, что свойство не установлено, и установил бы его в 100.
Если сделать свойство обнуляемым, то по умолчанию оно будет null. Но это заставит нас учитывать в коде, что Priority может null. В EF Core 8 можно настроить контрольное значение, т.е. значение, которое сообщает EF Core, что вместо него нужно вставить в БД значение по умолчанию:
…
b.Property(o => o.Priority)
.HasSentinel(-1)
.HasDefaultValueSql(100);
…
Здесь мы проверяем контрольное значение -1 (которое не используется в бизнес-логике), поэтому сохранение экземпляра с приоритетом 0 фактически становится возможным без костылей в реальной модели объекта.
Источник: https://dateo-software.de/blog/entity-framework-8