Язык программирования C#9 и платформа .NET5
private string _color = "Gold";public string Color{get => _color;set => _color = value;}Аннотации данных Entity Framework
Аннотации данных — это атрибуты С#, которые применяются для дальнейшего придания формы вашим сущностям. В табл. 22.8 описаны самые часто используемые аннотации данных, предназначенные для определения деталей того, как ваши сущностные классы и свойства сопоставляются с таблицами и полями базы данных. Аннотации данных переопределяют любые конфликтующие соглашения. В оставшемся материале главы и книги вы увидите еще много аннотаций, которые можно применять для уточнения сущностей в модели.
В следующем коде показан класс
с аннотацией, которая объявляет полеBaseEntityпервичным ключом. Вторая аннотация свойстваIdуказывает, что оно является столбцомIdв базе данных SQL Server. СвойствоIdentityв SQL Server будет столбцомTimeStamp(для проверки параллелизма, рассматриваемой позже в главе).timestamp/rowversionusing System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;public abstract class BaseEntity{<b> [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]</b>public int Id { get; set; }<b> [TimeStamp]</b>public byte[] TimeStamp { get; set; }}Вот класс
и аннотации данных, которые придают ему форму в базе данных:Carusing System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;using Microsoft.EntityFrameworkCore;<b>[Table("Inventory", Schema="dbo")]</b><b>[Index(nameof(MakeId), Name = "IX_Inventory_MakeId")]</b>public class Car : BaseEntity{<b> [Required, StringLength(50)]</b>public string Color { get; set; }<b> [Required, StringLength(50)]</b>public string PetName { get; set; }public int MakeId { get; set; }<b> [ForeignKey(nameof(MakeId))]</b>public Make MakeNavigation { get; set; }<b> [InverseProperty(nameof(Driver.Cars))]</b>public IEnumerable<Driver> Drivers { get; set; }}Атрибут
сопоставляет класс[Table]с таблицей Inventory в схемеCar(атрибутdboприменяется для изменения имени столбца или типа данных). Атрибут[Column]создает индекс на внешнем ключе[Index]. Два строковых поля установлены какMakeIdи имеющие максимальную длину([Required]) в 50 символов. АтрибутыStringLengthи[InverseProperty]объясняются в следующем разделе.[ForeignKey]Ниже перечислены отличия от соглашений EF Core:
• переименование таблицы из
вCars;Inventory• изменение типа данных столбца
изTimeStampнаvarbinary(max)в SQL Server;timestamp• установка типа данных и допустимости значения
для столбцовnullиColorвместоPetNameвnvarchar(max)/nullнеnvarchar(50)/;null• переименование индекса в
.MakeIdОстальные используемые аннотации соответствуют конфигурации, определенной соглашениями EF Core.
Если вы создадите миграцию и попробуете ее применить, то миграция потерпит неудачу. СУБД SQL Server не разрешает изменять любой тип данных существующего столбца на
. Столбец должен быть удален и затем воссоздан. К сожалению, инфраструктура миграций не позволяет удалять и воссоздавать, а пытается изменить столбец.timestampВот как проще всего решить проблему: поместить свойство
в комментарий внутри базовой сущности, создать и применить миграцию, убрать комментарий со свойстваTimeStampи затем создать и применить еще одну миграцию.TimeStampЗакомментируйте свойство
вместе с аннотацией данных и выполните следующие команды:TimeStampdotnet ef migrations add RemoveTimeStamp -o Migrations-c AutoLot.Samples.ApplicationDbContextdotnet ef database update RemoveTimeStamp-c AutoLot.Samples.ApplicationDbContextУберите комментарий со свойства
и аннотации данных и выполните показанные далее команды, чтобы добавить свойствоTimeStampв таблицу как столбецTimeStamp:timestampdotnet ef migrations add ReplaceTimeStamp -o Migrations-c AutoLot.Samples.
