Entity Framework: как быстрее написать код для работы с базой данных
2026-02-21 06:30 Diff

#Руководства

  • 30 окт 2019
  • 0

Код взаимодействия с базой данных может быть очень громоздким, однако его можно сократить, воспользовавшись Entity Framework.

 vlada_maestro / shutterstock

Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Entity Framework — это решение для работы с базами данных, которое используется в программировании на языках семейства .NET. Оно позволяет взаимодействовать с СУБД с помощью сущностей (entity), а не таблиц. Также код с использованием EF пишется гораздо быстрее.

Например, работая с базами данных напрямую, разработчик должен беспокоиться о подключении, подготовке SQL и параметров, отправке запросов и транзакций. На Entity Framework всё это делается автоматически — программист же работает непосредственно с сущностями и только говорит EF, что нужно сохранить изменения.

В этой статье будут разобраны основы применения Entity Framework, для понимания которых нужно владеть ADO.NET — пользоваться базами данных, писать SQL-запросы и работать с подключениями.

Подключить Entity Framework можно к любому проекту — от Xamarin до ASP.NET. Однако, чтобы не отвлекаться на работу с интерфейсом, здесь мы рассмотрим консольное приложение.

Для начала создайте проект Console Application в Visual Studio. Затем откройте менеджер пакетов NuGet:

И скачайте пакет с этим фреймворком:

Когда он установится, нужно подключиться к СУБД. Это делается с помощью файла конфигурации. Так как рассматривается консольное приложение, то надо открыть файл App.config:

<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> </startup> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework> </configuration>

В него вносится информация о СУБД. Для этого после элемента <configSections> добавляем следующее:

<connectionStrings> <add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=GameDB;Integrated Security=True;" providerName="System.Data.SqlClient"/> </connectionStrings>

Отсюда фреймворк будет брать connectionString. В этом примере приложение будет подключаться к SQLEXPRESS, но можно использовать и localdb. При этом достаточно указать любое название самой базы данных: если её не существует, EF создаст её сам. То же самое касается и всех таблиц.

Закончив с файлом конфигурации, можно приступать к работе с кодом.

В этой статье будет рассмотрен подход Code first, в котором сначала пишется код, а потом на его основе работает база данных.

В первую очередь необходимо создать сущность. Так как C# является объектно-ориентированным языком программирования, то сущность должна представлять собой класс.

public class Player { public int Id { get; set; } //Свойство с именем Id или PlayerId автоматически будет использоваться как primary key public string Nickname { get; set; } public int Rank { get; set; } }

Далее можно добавить класс, который будет использоваться для подключения к базе данных, — он называется контекстом:

public class PlayerContext : DbContext //Вся необходимая логика наследуется из DbContext { public PlayerContext() : base("DBConnection") //При инстанцировании объекты этого класса будут получать connectionString с названием DBConnection из файла конфигурации { } public DbSet<Player> Players { get; set; } //Таблица Players }

Несмотря на то что класс называется PlayerContext, его можно использовать для работы с любыми другими сущностями. Для этого нужно только добавить ещё несколько коллекций DbSet.

Название таблицы должно представлять собой множественное число от названия сущности: Player — Players, Person — People.

Теперь всё готово и можно приступить к работе с базой данных. Начать стоит с объявления первых объектов и их добавления в БД.

using (PlayerContext db = new PlayerContext()) //Создание подключения { //Объявление объектов Player player1 = new Player() { Nickname = "xKilleRx", Rank = 1 }; Player player2 = new Player() { Nickname = "AsSaSsIn", Rank = 5 }; //Добавление объектов в контекст db.Players.Add(player1); db.Players.Add(player2); db.SaveChanges(); //Чтобы добавленные объекты отправились в базу данных, нужно вызвать метод, сохраняющий изменения Console.WriteLine("Data saved."); }

Запустив программу с таким кодом, можно увидеть, что всё успешно сохранилось:

Теперь пора проверить, есть ли что-нибудь в базе данных в таблице Players. Для этого можно просто вывести данные из объектов в свойстве Players.

using (PlayerContext db = new PlayerContext()) //Создание подключения { var players = db.Players; //Получение объектов foreach (Player pl in players) { Console.WriteLine($" ID: {pl.Id} | Nickname: {pl.Nickname} | Rank: {pl.Rank}"); //Вывод всех объектов } }

Вот что должно получиться:

Тут видно, что Entity Framework автоматически указал свойство Id как первичный ключ, поэтому значения заполняются автоматически.

Чтобы выполнять более сложные операции, такие как выборка, редактирование или удаление, можно воспользоваться SQL-запросами. Однако гораздо проще будет заменить их на Linq — language integrated query (запросы, интегрированные в язык).

Linq добавляет в язык программирования синтаксис, напоминающий используемый в SQL. Например, для выборки можно использовать метод Where (), который позволяет получить все строки из таблицы, если они соответствуют утверждению.

var players = db.Players.Where(p => p.Rank >= 10); //Получение всех игроков, чей ранг выше или равен 10

В отличие от ADO.NET, тут будет получена не строка из таблицы, а сразу объекты, которые можно будет тут же использовать без предварительной подготовки.

Вот как выглядит редактирование строк в Entity Framework:

using (PlayerContext db = new PlayerContext()) //Создание подключения { Console.WriteLine("Editing..."); var players = db.Players.Where(p => p.Id == 2); //Получение игрока с Id, равным 2 players.FirstOrDefault().Nickname = "New nick"; //Так как данные вносятся в список, то нужно получить первый элемент db.SaveChanges(); //Сохранение изменений } using (PlayerContext db = new PlayerContext()) //Чтобы проверить, произошли ли изменения, новые данные получаются в другом контексте { var players = db.Players.Where(p => p.Id == 2); var pl = players.FirstOrDefault(); Console.WriteLine($" ID: {pl.Id} | Nickname: {pl.Nickname} | Rank: {pl.Rank}"); }

Вот что будет выведено в результате работы такого кода:

Никнейм игрока был успешно изменён. Теперь можно попробовать удалить эту сущность из базы данных.

using (PlayerContext db = new PlayerContext()) { Console.WriteLine("Deleting..."); var players = db.Players.Where(p => p.Id == 2); if (players.FirstOrDefault() != null) { db.Players.Remove(players.FirstOrDefault()); //Чтобы удалить объект, его нужно просто удалить из списка Players } db.SaveChanges(); } using (PlayerContext db = new PlayerContext()) { var players = db.Players.Where(p => p.Id == 2); var pl = players.FirstOrDefault(); if (pl != null) { Console.WriteLine($" ID: {pl.Id} | Nickname: {pl.Nickname} | Rank: {pl.Rank}"); } else { Console.WriteLine("There is no such player!"); } }

Тут уже можно увидеть, что проверяется, не равен ли объект null, потому что иначе будет вызвано исключение NullReferenceException.

Вот каким будет вывод:

Entity Framework позволяет значительно сократить код работы с базами данных. При этом он предоставляет большие возможности. Например, можно использовать:

  • foreign keys;
  • связи one-to-one, one-to-many и many-to-many;
  • параметризацию запросов;
  • хранимые процедуры.

Однако стоит учитывать, что EF выступает прослойкой между приложением и базой данных, поэтому может ухудшаться производительность. Для небольших проектов это допустимо, но если программа должна работать под большой нагрузкой, то лучше использовать чистый ADO.NET.

Бесплатный курс по Python ➞
Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу