Полезные функции EF Core 8. Начало
Рассмотрим набор функций Entity Framework Core 8, которые могут быть полезны многим.
1. Поддержка сопоставления коллекций примитивов
Коллекция примитивов - это набор значений примитивного типа для провайдера БД (обычно это числа и строки, перечисления). Раньше этого можно было достичь с помощью специального кода, а теперь это доступно прямо из коробки. Например, теперь можно легко сопоставить свойство:
public List<string> Tags { get; }с его конфигурацией
builder.Property(o => o.Tags);
Тогда для следующей таблицы:
CREATE TABLE "Tweets" (
"Id" INTEGER NOT NULL CONSTRAINT "PK_Tweets" PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL,
"Tags" TEXT NOT NULL
);
EF сохранит коллекцию значений в (в данном случае) одной строке и распарсит их обратно в список объектов, которые вы ожидаете при запросе из БД, что довольно удобно. Это также будет работать для таких типов, как uint, bool, DateOnly, DateTime, Uri.
Uri? Да, функция будет работать и для типов, для которых в EF есть встроенные преобразователи!
2. Сложные типы
Говоря о типах объектов, которые хранятся и сопоставляются с реляционными БД с помощью Entity Framework, можно грубо выделить 3 категории:
- Типы с одним значением: int, string, Guid, DateTime, и т.п.
- Структурированные объекты, однозначно определённые с помощью ключа (сущности).
- Структурированные объекты, не определяемые ключом (типы-значения).
Начиная с EF Core 8 появился хороший способ сопоставления третьей категории объектов. Рассмотрим простой пример модели:
public class Price
{
public decimal Amount { get; set; }
public string Currency { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Price Price { get; set; }
}
Конфигурация для сущности Product может выглядеть так:
public void Configure(EntityTypeBuilder<Product> b)
{
b.ToTable("Products");
b.HasKey(p => p.Id);
…
b.ComplexProperty(p => p.Price);
}
Мы получим примерно такую таблицу:
CREATE TABLE "Products" (
"Id" INTEGER NOT NULL CONSTRAINT "PK_Products" PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL,
"Price_Amount" TEXT NOT NULL,
"Price_Currency" INTEGER NOT NULL
);
Как видим, EF Core автоматически объединит свойства сложного объекта в соответствующее количество столбцов.
Примечание. В настоящее время невозможно сопоставить сложные типы с другой таблицей.
Пример выше может привести к проблемам из-за изменяемости объекта Price. Если продукт имеет две цены (например, розничную и оптовую), которым мы изначально назначили один и тот же экземпляр Price, при изменении значения одной цены результирующий оператор SQL фактически изменит обе. Эту проблему можно легко обойти, сделав базовую сущность Price неизменяемой (или записью). Вот тестовый пример этого поведения.
Окончание следует…
Источник: https://dateo-software.de/blog/entity-framework-8