Ответ
Метод Add() в Entity Framework Core отслеживает новую сущность, помечая ее для вставки (INSERT) в базу данных. Сама вставка происходит не сразу, а при следующем вызове SaveChanges() или SaveChangesAsync().
Как это работает:
- Вы вызываете
DbSet<T>.Add(entity)илиDbContext.Add(entity). - EF Core начинает отслеживать эту сущность и устанавливает ее состояние (
EntityState) вAdded. - При вызове
SaveChanges()EF Core генерирует и выполняет соответствующий SQL-запросINSERT.
Пример базового использования:
using var context = new BloggingContext();
var newBlog = new Blog { Url = "https://example.com" };
context.Blogs.Add(newBlog); // Состояние сущности newBlog становится 'Added'
// В этот момент INSERT в БД еще НЕ выполнен
Console.WriteLine(context.Entry(newBlog).State); // Выведет: Added
// INSERT выполняется здесь
int recordsAffected = await context.SaveChangesAsync();
Console.WriteLine($"Добавлено записей: {recordsAffected}");
Важные особенности и альтернативы:
- Каскадное добавление: Если у новой сущности есть связанные сущности в навигационных свойствах, и эти связи настроены (например,
Required), они также будут помечены какAddedи вставлены каскадно. AddRange(): Для добавления коллекции сущностей эффективнее использоватьAddRange(), чтобы минимизировать накладные расходы на отслеживание.context.Blogs.AddRange(blog1, blog2, blog3);- Проверка существования:
Add()не проверяет, существует ли уже такая сущность в БД. Если добавить сущность с тем же первичным ключом, который уже отслеживается, будет выброшено исключение. - Производительность: Для массовой вставки тысяч записей
Add()/SaveChanges()неэффективен. ИспользуйтеAddRange()с однойSaveChanges()или специализированные библиотеки вроде EFCore.BulkExtensions или SqlBulkCopy.