Entity Framework: как быстрее написать код для работы с базой данных

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

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

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

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

Евгений Кучерявый

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


Как установить
Entity Framework

Подключить 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 создаст её сам. То же самое касается и всех таблиц.

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

Как использовать
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.");
}

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

Теперь пора проверить, есть ли что-нибудь в базе данных в таблице 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 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}");
}

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

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

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.

Лучше узнать, как взаимодействовать с базой данных, в том числе и с помощью EF, вы сможете на курсе «Профессия C#-разработчик».

Курс

Профессия C#-разработчик


130 часов — и вы научитесь писать программы на языке, созданном Microsoft. Вы создадите 5 проектов для портфолио, даже если до этого никогда не программировали. После обучения — гарантированное трудоустройство.

Хочешь получать крутые статьи по программированию?
Подпишись на рассылку Skillbox