Entity Framework Core (EF Core) — это мощный, легковесный и кроссплатформенный объектно-реляционный маппер (ORM) от Microsoft, который стал незаменимым инструментом для .NET разработчиков. Он позволяет работать с базами данных, используя знакомые объекты C#, избавляя от необходимости писать тонны шаблонного SQL-кода. В этой статье мы погрузимся в практические примеры, которые помогут вам освоить EF Core от простых запросов до сложных сценариев.
Что такое Entity Framework Core и зачем он нужен?
Представьте, что вам больше не нужно вручную прописывать каждый JOIN и WHERE. Вместо этого вы просто работаете с коллекциями объектов, а EF Core волшебным образом транслирует ваши операции в SQL-запросы. Это и есть его главная магия. Он поддерживает множество баз данных: SQL Server, PostgreSQL, MySQL, SQLite и другие.
EF Core — это эволюция классического Entity Framework. Он быстрее, модульнее и работает не только на Windows, но и на Linux и macOS благодаря .NET Core/.NET 5+.
Практические примеры: от простого к сложному
Лучший способ понять EF Core — увидеть его в действии. Рассмотрим ключевые сценарии.
1. Базовая настройка и модель данных
Сначала определим простые модели (сущности) и контекст базы данных (DbContext).
public class Blog
{
public int Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public List Posts { get; set; } = new(); // Навигационное свойство
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; } // Внешний ключ
public Blog Blog { get; set; } // Навигационное свойство
}
public class BloggingContext : DbContext
{
public DbSet Blogs { get; set; }
public DbSet Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=BloggingDB;Trusted_Connection=True;");
}
2. CRUD-операции: создание, чтение, обновление, удаление
Работа с данными интуитивно понятна.
- Создание (Create):
using var db = new BloggingContext(); var blog = new Blog { Title = "EF Core Guide", Url = "https://example.com" }; db.Blogs.Add(blog); await db.SaveChangesAsync(); // INSERT в БД - Чтение (Read) с фильтрацией и включением связанных данных:
var blogsWithPosts = await db.Blogs .Where(b => b.Title.Contains("Core")) .Include(b => b.Posts) // Жадная загрузка (Eager Loading) .ToListAsync(); - Обновление (Update):
var blog = await db.Blogs.FindAsync(1); blog.Title = "Обновленное название"; await db.SaveChangesAsync(); // UPDATE - Удаление (Delete):
var blog = await db.Blogs.FindAsync(1); db.Blogs.Remove(blog); await db.SaveChangesAsync(); // DELETE
Все изменения (Add, Update, Remove) накапливаются в памяти до вызова SaveChangesAsync(). Это позволяет объединять несколько операций в одну транзакцию.
3. Миграции базы данных
EF Core миграции — это система контроля версий схемы вашей БД. После изменения моделей выполните в консоли диспетчера пакетов (Package Manager Console):
Add-Migration InitialCreate— создает миграцию на основе текущих моделей.Update-Database— применяет миграцию к БД, создавая или изменяя таблицы.
Это делает процесс эволюции схемы данных безопасным и воспроизводимым.
4. Выполнение сырых SQL-запросов
Иногда ORM не справляется со сложными запросами. Для этого есть возможность выполнить свой SQL:
var blogs = await db.Blogs
.FromSqlRaw("SELECT * FROM Blogs WHERE Url LIKE '%example%'")
.ToListAsync();
// Или для операций, не возвращающих сущности
await db.Database.ExecuteSqlRawAsync("DELETE FROM Posts WHERE BlogId = {0}", blogId);
Лучшие практики и частые ошибки
- N+1 проблема: Избегайте циклических обращений к БД внутри циклов. Используйте
.Include()или.ThenInclude()для жадной загрузки или.Select()для явной проекции. - Отслеживание изменений (Tracking): Для операций только для чтения используйте
.AsNoTracking()для увеличения производительности. - Асинхронность: Всегда используйте асинхронные методы (
ToListAsync(),SaveChangesAsync()) в веб-приложениях для масштабируемости. - Внедрение зависимостей (DI): В ASP.NET Core регистрируйте контекст в
Startup.csилиProgram.csи внедряйте его в контроллеры через конструктор.
FAQ: Часто задаваемые вопросы по Entity Framework Core
В чем разница между Entity Framework и Entity Framework Core?
EF Core — это переписанная с нуля, кроссплатформенная и более легковесная версия классического EF. У него меньше "магии", но больше контроля и производительности. Для новых проектов всегда выбирайте EF Core.
Как выбрать стратегию загрузки связанных данных?
Есть три основных способа: Eager Loading (жадная, с помощью .Include()), Lazy Loading (ленивая, требует установки пакета и прокси-классов) и Explicit Loading (явная, с помощью .Entry().Collection().Load()). Для большинства сценариев, где вы заранее знаете, какие данные нужны, используйте Eager Loading.
Как улучшить производительность EF Core?
Ключевые моменты: используйте .AsNoTracking(), фильтруйте данные на стороне БД (в .Where()), а не в памяти, выбирайте только нужные поля с .Select(), используйте индексы в БД и минимизируйте количество запросов.
Поддерживает ли EF Core NoSQL базы данных?
Официально EF Core ориентирован на реляционные БД. Однако существуют сторонние провайдеры для некоторых NoSQL-систем, например, Cosmos DB имеет официального провайдера от Microsoft.
Стоит ли использовать EF Core в микросервисной архитектуре?
Да, но с осторожностью. Он отлично подходит для быстрой разработки внутри сервиса. Однако избегайте использования миграций EF Core для управления схемой БД в production-среде микросервисов — это может нарушить их независимость. Лучше использовать отдельные инструменты для миграций БД (например, Flyway, DbUp).