Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
// ApplicationDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>(entity =>
{
...
<b> entity.Property(e => e.IsDrivable).HasDefaultValue(true);</b>
});
В случае если вы сохраните новую запись с
IsDrivable = false
false
IsDrivable
true
null
Другое решение предлагается инфраструктурой EF Core, в частности, ее работой с поддерживающими полями. Вспомните, что если поддерживающее поле существует (и идентифицируется как таковое для свойства через соглашение, аннотацию данных или Fluent API), тогда для действий по чтению и записи EF Core будет использовать поддерживающее поле, а не открытое свойство.
Если вы модифицируете
IsDrivable
null
null
null
null
false
public class Car
{
...
private bool? _isDrivable;
public bool IsDrivable
{
get => _isDrivable ?? true;
set => _isDrivable = value;
}
Для информирования EF Core о поддерживающем поле используется Fluent API:
modelBuilder.Entity<Car>(entity =>
{
entity.Property(p => p.IsDrivable)
<b> .HasField("_isDrivable")</b>
.HasDefaultValue(true);
});
На заметку! В приведенном примере вызов метода
HasField()
Исполняющая среда EF Core транслирует поле в показанное ниже определение SQL:
CREATE TABLE [dbo].[Inventory](
...
<b> [IsDrivable] [BIT] NOT NULL,</b>
...
GO
<b>ALTER TABLE [dbo].[Inventory] ADD DEFAULT (CONVERT([BIT],(1)))</b>
<b>FOR [IsDrivable]</b>
GO
Вычисляемые столбцы
Столбцы также могут вычисляться на основе возможностей хранилища данных. Для SQL Server есть два варианта: вычислять значение, основываясь на других полях в той же самой записи, либо использовать скалярную функцию. Скажем, чтобы создать в таблице
Inventory
PetName
Color
DisplayName
HasComputedColumnSql()
modelBuilder.Entity<Car>(entity =>
{
entity.Property(p => p.FullName)
<b> .HasComputedColumnSql("[PetName] + ' (' + [Color] + ')'");</b>
});
В версии EF Core 5 появилась возможность сохранения вычисляемых значений, так что значение вычисляется только при создании или обновлении строки. Хотя в SQL Server упомянутая возможность поддерживается, она присутствует не во всех хранилищах данных, поэтому проверяйте документацию по своему поставщику баз данных:
modelBuilder.Entity<Car>(entity =>
{
entity.Property(p => p.FullName)
.HasComputedColumnSql("[PetName] + ' (' + [Color] + ')'", <b>stored:true</b>);
});
Отношения "один ко многим"
Чтобы определить отношение "один ко многим" с помощью Fluent API, выберите одну из сущностей, подлежащих обновлению. Обе стороны навигационной цепочки устанавливаются в одном блоке кода:
modelBuilder.Entity<Car>(entity =>
{
...
entity.HasOne(d => d.MakeNavigation)
.WithMany(p => p.Cars)
.HasForeignKey(d => d.MakeId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Inventory_Makes_MakeId");
});
Если вы выберете в качестве основы для конфигурации навигационной сущности главную сущность, тогда код будет выглядеть примерно так:
modelBuilder.Entity<Make>(entity =>
{