Язык программирования C#9 и платформа .NET5
ApplicationDbContextdotnet ef database update ReplaceTimeStamp-c AutoLot.Samples.ApplicationDbContextТеперь база данных соответствует вашей модели.
Аннотации и навигационные свойства
Аннотация
позволяет EF Core знать, какое свойство является поддерживающим полем для навигационного свойства. По соглашениюForeignKeyавтоматически станет свойством внешнего ключа, но в предыдущем примере оно было установлено явно. Такой подход обеспечивает отличающиеся стили именования, а также наличие в таблице более одного внешнего ключа. Кроме того, улучшается читабельность кода.<ИмяТипа>IdСвойство
информирует EF Core о способе связывания таблиц, указывая навигационное свойство в других сущностях, которое направляет обратно в текущую сущность. СвойствоInversePropertyтребуется, когда сущность связана с другой сущностью несколько раз, и вдобавок делает код более читабельным.InversePropertyИнтерфейс Fluent API
С помощью интерфейса Fluent API сущности приложения конфигурируются посредством кода С#. Методы предоставляются экземпляром
, доступным в методеModelBuilderклассаOnModelCreating(). Интерфейс Fluent API является самым мощным способом конфигурирования и переопределяет любые конфликтующие между собой соглашения или аннотации данных. Некоторые конфигурационные параметры доступны только через Fluent API, скажем, стандартные значения для настроек и каскадное поведение для навигационных свойств.DbContextОтображение классов и свойств
В следующем коде воспроизведен предыдущий пример
с использованием Fluent API вместо аннотаций данных (здесь не показаны навигационные свойства, которые будут раскрыты ниже):CarmodelBuilder.Entity<Car>(entity =>{entity.ToTable("Inventory","dbo");entity.HasKey(e=>e.Id);entity.HasIndex(e => e.MakeId, "IX_Inventory_MakeId");entity.Property(e => e.Color).IsRequired().HasMaxLength(50);entity.Property(e => e.PetName).IsRequired().HasMaxLength(50);entity.Property(e => e.TimeStamp).IsRowVersion().IsConcurrencyToken();});Если создать и запустить миграцию прямо сейчас, то вы обнаружите, что ничего не изменилось, поскольку вызываемые методы Fluent API соответствуют текущей конфигурации, определенной соглашениями и аннотациями данных.
Стандартные значения
Интерфейс Fluent API предлагает методы, позволяющие устанавливать стандартные значения для столбцов. Стандартное значение может иметь тип значения или быть строкой SQL. Например, вот как установить стандартное значение
для новой сущностиColorвCar:BlackmodelBuilder.Entity<Car>(entity =>{...entity.Property(e => e.Color).HasColumnName("CarColor").IsRequired().HasMaxLength(50)<b> .HasDefaultValue("Black");</b>});Чтобы установить значение для функции базы данных (вроде
), применяйте методgetdate(). Предположим, что в классHasDefaultValueSql()было добавлено свойствоCarпо имениDateTime, а стандартным значением должна быть текущая дата, получаемая с использованием методаDateBuiltв SQL Server. Столбцы конфигурируются следующим образом:getdate()modelBuilder.Entity<Car>(entity =>{...entity.Property(e => e.DateBuilt).HasDefaultValueSql("getdate()");});Как и в случае применения SQL для вставки записи, если свойство, которое отображается на столбец со стандартным значением, имеет значение, когда EF Core вставляет запись, то вместо стандартного значения столбца будет использоваться значение свойства. Если значение свойства равно
, тогда применяется стандартное значение столбца.nullПроблема возникает при наличии стандартного значения у типа данных свойства. Вспомните, что стандартное значение для числовых типов составляет
, а для булевских —0. Если вы установите значение числового свойства вfalseили булевского свойства в0и затем вставите такую сущность, тогда инфраструктура EF Core будет трактовать это свойство как не имеющее установленного значения. При отображении свойства на столбец со стандартным значением используется стандартное значение в определении столбца.falseНапример, добавьте в класс
свойство типаCarпо имениbool. Установите вIsDrivableстандартное значение для отображения свойства на столбец:true// Car.cspublic class Car : BaseEntity{...<b> public bool IsDrivable { get; set; }</b>}