Если создать и запустить миграцию прямо сейчас, то вы обнаружите, что ничего не изменилось, поскольку вызываемые методы Fluent API соответствуют текущей конфигурации, определенной соглашениями и аннотациями данных.
Стандартные значения
Интерфейс Fluent API предлагает методы, позволяющие устанавливать стандартные значения для столбцов. Стандартное значение может иметь тип значения или быть строкой SQL. Например, вот как установить стандартное значение Color
Car в Black:modelBuilder.Entity
{
...
entity.Property(e => e.Color)
.HasColumnName("CarColor")
.IsRequired
.HasMaxLength(50)
.HasDefaultValue("Black");
});
Чтобы установить значение для функции базы данных (вроде getdate
HasDefaultValueSql. Предположим, что в класс Car было добавлено свойство DateTime по имени DateBuilt, а стандартным значением должна быть текущая дата, получаемая с использованием метода getdate в SQL Server. Столбцы конфигурируются следующим образом:modelBuilder.Entity
{
...
entity.Property(e => e.DateBuilt)
.HasDefaultValueSql("getdate");
});
Как и в случае применения SQL для вставки записи, если свойство, которое отображается на столбец со стандартным значением, имеет значение, когда EF Core вставляет запись, то вместо стандартного значения столбца будет использоваться значение свойства. Если значение свойства равно null
Проблема возникает при наличии стандартного значения у типа данных свойства. Вспомните, что стандартное значение для числовых типов составляет 0
false. Если вы установите значение числового свойства в 0 или булевского свойства в false и затем вставите такую сущность, тогда инфраструктура EF Core будет трактовать это свойство как Например, добавьте в класс Car
bool по имени IsDrivable. Установите в true стандартное значение для отображения свойства на столбец:// Car.cs
public class Car : BaseEntity
{
...
public bool IsDrivable { get; set; }
}
// ApplicationDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity
{
...
entity.Property(e => e.IsDrivable).HasDefaultValue(true);
});
В случае если вы сохраните новую запись с IsDrivable = false
false игнорируется (т.к. оно является стандартным значением для булевского типа) и будет применяться стандартное значение. Таким образом, значение для IsDrivable всегда будет равно true! Одно из решений предусматривает превращение вашего открытого свойства (и, следовательно, столбца) в допускающее null, но это может не соответствовать бизнес-потребностям.Другое решение предлагается инфраструктурой EF Core, в частности, ее работой с поддерживающими полями. Вспомните, что если поддерживающее поле существует (и идентифицируется как таковое для свойства через соглашение, аннотацию данных или Fluent API), тогда для действий по чтению и записи EF Core будет использовать поддерживающее поле, а не открытое свойство.
Если вы модифицируете IsDrivable
null (но оставите свойство не допускающим null), то EF Core будет выполнять чтение и запись, используя поддерживающее поле, а не свойство. Стандартным значением для булевского типа, допускающего null, является null — не false. Описанное изменение обеспечит ожидаемое поведение свойства:public class Car
{
...
private bool? _isDrivable;
public bool IsDrivable
{
get => _isDrivable ?? true;
set => _isDrivable = value;
}
Для информирования EF Core о поддерживающем поле используется Fluent API:
modelBuilder.Entity
{
entity.Property(p => p.IsDrivable)
.HasField("_isDrivable")
.HasDefaultValue(true);
});
На заметку!
В приведенном примере вызов методаHasField не обязателен, потому что имя поддерживающего поля следует соглашениям об именовании. Он включен в целях демонстрации применения Fluent API для указания поддерживающего поля.Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT