Entity Framework: как быстрее написать код для работы с базой данных
Код взаимодействия с базой данных может быть очень громоздким, однако его можно сократить, воспользовавшись Entity Framework.
![](https://248006.selcdn.ru/main/iblock/326/3262ee7f5dd656d74c9d27bd61f5284f/3d3a3cc9d47969b4d850559e80f50423.png)
![](https://248006.selcdn.ru/main/iblock/326/3262ee7f5dd656d74c9d27bd61f5284f/3d3a3cc9d47969b4d850559e80f50423.png)
vlada_maestro / shutterstock
Entity Framework — это решение для работы с базами данных, которое используется в программировании на языках семейства .NET. Оно позволяет взаимодействовать с СУБД с помощью сущностей (entity), а не таблиц. Также код с использованием EF пишется гораздо быстрее.
Например, работая с базами данных напрямую, разработчик должен беспокоиться о подключении, подготовке SQL и параметров, отправке запросов и транзакций. На Entity Framework всё это делается автоматически — программист же работает непосредственно с сущностями и только говорит EF, что нужно сохранить изменения.
В этой статье будут разобраны основы применения Entity Framework, для понимания которых нужно владеть ADO.NET — пользоваться базами данных, писать SQL-запросы и работать с подключениями.
Как установить Entity Framework
Подключить Entity Framework можно к любому проекту — от Xamarin до ASP.NET. Однако, чтобы не отвлекаться на работу с интерфейсом, здесь мы рассмотрим консольное приложение.
Для начала создайте проект Console Application в Visual Studio. Затем откройте менеджер пакетов NuGet:
![](https://248006.selcdn.ru/main/upload/setka_images/13353029102019_e3ea06ecc4efe66fd609360c227a5daace25eda6.png)
И скачайте пакет с этим фреймворком:
![](https://248006.selcdn.ru/main/upload/setka_images/13353029102019_d58f50d1222620cd1cfe95da3a91221bd0d26e65.png)
Когда он установится, нужно подключиться к СУБД. Это делается с помощью файла конфигурации. Так как рассматривается консольное приложение, то надо открыть файл 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 создаст её сам. То же самое касается и всех таблиц.
Закончив с файлом конфигурации, можно приступать к работе с кодом.
Как использовать Entity Framework
В этой статье будет рассмотрен подход 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.");
}
Запустив программу с таким кодом, можно увидеть, что всё успешно сохранилось:
![](https://248006.selcdn.ru/main/upload/setka_images/13353029102019_db52642fc67f6c7c46657360f234a883af322464.png)
Теперь пора проверить, есть ли что-нибудь в базе данных в таблице 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}"); //Вывод всех объектов
}
}
Вот что должно получиться:
![](https://248006.selcdn.ru/main/upload/setka_images/13353029102019_7b64da46b2dc4329c15be64aeef9e636261e678c.png)
Тут видно, что Entity Framework автоматически указал свойство Id как первичный ключ, поэтому значения заполняются автоматически.
Чтобы выполнять более сложные операции, такие как выборка, редактирование или удаление, можно воспользоваться SQL-запросами. Однако гораздо проще будет заменить их на Linq — language integrated query (запросы, интегрированные в язык).
Как использовать Linq to Entities
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}");
}
Вот что будет выведено в результате работы такого кода:
![](https://248006.selcdn.ru/main/upload/setka_images/13353029102019_6a4e9b3ae3023faad72ace61e6264ce47ed78056.png)
Никнейм игрока был успешно изменён. Теперь можно попробовать удалить эту сущность из базы данных.
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.
Вот каким будет вывод:
![](https://248006.selcdn.ru/main/upload/setka_images/13352929102019_27e9aa5bdf801f94f7728fe14d1ac08405e5a691.png)
Заключение
Entity Framework позволяет значительно сократить код работы с базами данных. При этом он предоставляет большие возможности. Например, можно использовать:
- foreign keys;
- связи one-to-one, one-to-many и many-to-many;
- параметризацию запросов;
- хранимые процедуры.
Однако стоит учитывать, что EF выступает прослойкой между приложением и базой данных, поэтому может ухудшаться производительность. Для небольших проектов это допустимо, но если программа должна работать под большой нагрузкой, то лучше использовать чистый ADO.NET.