0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#Руководства</a></p>
1
<p><a>#Руководства</a></p>
2
<ul><li>30 окт 2019</li>
2
<ul><li>30 окт 2019</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Код взаимодействия с базой данных может быть очень громоздким, однако его можно сократить, воспользовавшись Entity Framework.</p>
4
</ul><p>Код взаимодействия с базой данных может быть очень громоздким, однако его можно сократить, воспользовавшись Entity Framework.</p>
5
<p> vlada_maestro / shutterstock</p>
5
<p> vlada_maestro / shutterstock</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
7
<p>Entity Framework - это решение для работы с базами данных, которое используется в программировании на языках семейства<a>.NET</a>. Оно позволяет взаимодействовать с СУБД с помощью сущностей<em>(entity)</em>, а не таблиц. Также код с использованием EF пишется гораздо быстрее.</p>
7
<p>Entity Framework - это решение для работы с базами данных, которое используется в программировании на языках семейства<a>.NET</a>. Оно позволяет взаимодействовать с СУБД с помощью сущностей<em>(entity)</em>, а не таблиц. Также код с использованием EF пишется гораздо быстрее.</p>
8
<p>Например, работая с базами данных напрямую, разработчик должен беспокоиться о подключении, подготовке SQL и параметров, отправке запросов и транзакций. На Entity Framework всё это делается автоматически - программист же работает непосредственно с сущностями и только говорит EF, что нужно сохранить изменения.</p>
8
<p>Например, работая с базами данных напрямую, разработчик должен беспокоиться о подключении, подготовке SQL и параметров, отправке запросов и транзакций. На Entity Framework всё это делается автоматически - программист же работает непосредственно с сущностями и только говорит EF, что нужно сохранить изменения.</p>
9
<p>В этой статье будут разобраны основы применения Entity Framework, для понимания которых нужно владеть ADO.NET - пользоваться базами данных, писать SQL-запросы и работать с подключениями.</p>
9
<p>В этой статье будут разобраны основы применения Entity Framework, для понимания которых нужно владеть ADO.NET - пользоваться базами данных, писать SQL-запросы и работать с подключениями.</p>
10
<p>Подключить Entity Framework можно к любому проекту - от Xamarin до ASP.NET. Однако, чтобы не отвлекаться на работу с интерфейсом, здесь мы рассмотрим консольное приложение.</p>
10
<p>Подключить Entity Framework можно к любому проекту - от Xamarin до ASP.NET. Однако, чтобы не отвлекаться на работу с интерфейсом, здесь мы рассмотрим консольное приложение.</p>
11
<p>Для начала создайте проект<em>Console Application</em>в Visual Studio. Затем откройте менеджер пакетов<em>NuGet</em>:</p>
11
<p>Для начала создайте проект<em>Console Application</em>в Visual Studio. Затем откройте менеджер пакетов<em>NuGet</em>:</p>
12
<p>И скачайте пакет с этим фреймворком:</p>
12
<p>И скачайте пакет с этим фреймворком:</p>
13
<p>Когда он установится, нужно подключиться к СУБД. Это делается с помощью файла конфигурации. Так как рассматривается консольное приложение, то надо открыть файл<em>App.config</em>:</p>
13
<p>Когда он установится, нужно подключиться к СУБД. Это делается с помощью файла конфигурации. Так как рассматривается консольное приложение, то надо открыть файл<em>App.config</em>:</p>
14
<?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><p>В него вносится информация о СУБД. Для этого после элемента<em><configSections></em>добавляем следующее:</p>
14
<?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><p>В него вносится информация о СУБД. Для этого после элемента<em><configSections></em>добавляем следующее:</p>
15
<connectionStrings> <add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=GameDB;Integrated Security=True;" providerName="System.Data.SqlClient"/> </connectionStrings><p>Отсюда фреймворк будет брать<em>connectionString</em>. В этом примере приложение будет подключаться к <em>SQLEXPRESS</em>, но можно использовать и <em>localdb</em>. При этом достаточно указать любое название самой базы данных: если её не существует, EF создаст её сам. То же самое касается и всех таблиц.</p>
15
<connectionStrings> <add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=GameDB;Integrated Security=True;" providerName="System.Data.SqlClient"/> </connectionStrings><p>Отсюда фреймворк будет брать<em>connectionString</em>. В этом примере приложение будет подключаться к <em>SQLEXPRESS</em>, но можно использовать и <em>localdb</em>. При этом достаточно указать любое название самой базы данных: если её не существует, EF создаст её сам. То же самое касается и всех таблиц.</p>
16
<p>Закончив с файлом конфигурации, можно приступать к работе с кодом.</p>
16
<p>Закончив с файлом конфигурации, можно приступать к работе с кодом.</p>
17
<p>В этой статье будет рассмотрен подход<strong>Code first</strong>, в котором сначала пишется код, а потом на его основе работает база данных.</p>
17
<p>В этой статье будет рассмотрен подход<strong>Code first</strong>, в котором сначала пишется код, а потом на его основе работает база данных.</p>
18
<p>В первую очередь необходимо создать сущность. Так как C# является<a>объектно-ориентированным</a>языком программирования, то сущность должна представлять собой класс.</p>
18
<p>В первую очередь необходимо создать сущность. Так как C# является<a>объектно-ориентированным</a>языком программирования, то сущность должна представлять собой класс.</p>
19
public class Player { public int Id { get; set; } //Свойство с именем Id или PlayerId автоматически будет использоваться как primary key public string Nickname { get; set; } public int Rank { get; set; } }<p>Далее можно добавить класс, который будет использоваться для подключения к базе данных, - он называется контекстом:</p>
19
public class Player { public int Id { get; set; } //Свойство с именем Id или PlayerId автоматически будет использоваться как primary key public string Nickname { get; set; } public int Rank { get; set; } }<p>Далее можно добавить класс, который будет использоваться для подключения к базе данных, - он называется контекстом:</p>
20
public class PlayerContext : DbContext //Вся необходимая логика наследуется из DbContext { public PlayerContext() : base("DBConnection") //При инстанцировании объекты этого класса будут получать connectionString с названием DBConnection из файла конфигурации { } public DbSet<Player> Players { get; set; } //Таблица Players }<p>Несмотря на то что класс называется<em>PlayerContext</em>, его можно использовать для работы с любыми другими сущностями. Для этого нужно только добавить ещё несколько коллекций<em>DbSet</em>.</p>
20
public class PlayerContext : DbContext //Вся необходимая логика наследуется из DbContext { public PlayerContext() : base("DBConnection") //При инстанцировании объекты этого класса будут получать connectionString с названием DBConnection из файла конфигурации { } public DbSet<Player> Players { get; set; } //Таблица Players }<p>Несмотря на то что класс называется<em>PlayerContext</em>, его можно использовать для работы с любыми другими сущностями. Для этого нужно только добавить ещё несколько коллекций<em>DbSet</em>.</p>
21
<p><strong>Название таблицы должно представлять собой множественное число от названия сущности:<em>Player - Players, Person - People.</em></strong></p>
21
<p><strong>Название таблицы должно представлять собой множественное число от названия сущности:<em>Player - Players, Person - People.</em></strong></p>
22
<p>Теперь всё готово и можно приступить к работе с базой данных. Начать стоит с объявления первых объектов и их добавления в БД.</p>
22
<p>Теперь всё готово и можно приступить к работе с базой данных. Начать стоит с объявления первых объектов и их добавления в БД.</p>
23
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."); }<p>Запустив программу с таким кодом, можно увидеть, что всё успешно сохранилось:</p>
23
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."); }<p>Запустив программу с таким кодом, можно увидеть, что всё успешно сохранилось:</p>
24
<p>Теперь пора проверить, есть ли что-нибудь в базе данных в таблице<em>Players</em>. Для этого можно просто вывести данные из объектов в свойстве<em>Players</em>.</p>
24
<p>Теперь пора проверить, есть ли что-нибудь в базе данных в таблице<em>Players</em>. Для этого можно просто вывести данные из объектов в свойстве<em>Players</em>.</p>
25
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}"); //Вывод всех объектов } }<p>Вот что должно получиться:</p>
25
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}"); //Вывод всех объектов } }<p>Вот что должно получиться:</p>
26
<p>Тут видно, что Entity Framework автоматически указал свойство<em>Id</em>как первичный ключ, поэтому значения заполняются автоматически.</p>
26
<p>Тут видно, что Entity Framework автоматически указал свойство<em>Id</em>как первичный ключ, поэтому значения заполняются автоматически.</p>
27
<p>Чтобы выполнять более сложные операции, такие как выборка, редактирование или удаление, можно воспользоваться SQL-запросами. Однако гораздо проще будет заменить их на <em><strong>Linq</strong> - language integrated query (запросы, интегрированные в язык)</em>.</p>
27
<p>Чтобы выполнять более сложные операции, такие как выборка, редактирование или удаление, можно воспользоваться SQL-запросами. Однако гораздо проще будет заменить их на <em><strong>Linq</strong> - language integrated query (запросы, интегрированные в язык)</em>.</p>
28
<p>Linq добавляет в язык программирования синтаксис, напоминающий используемый в SQL. Например, для выборки можно использовать метод<em>Where ()</em>, который позволяет получить все строки из таблицы, если они соответствуют утверждению.</p>
28
<p>Linq добавляет в язык программирования синтаксис, напоминающий используемый в SQL. Например, для выборки можно использовать метод<em>Where ()</em>, который позволяет получить все строки из таблицы, если они соответствуют утверждению.</p>
29
var players = db.Players.Where(p => p.Rank >= 10); //Получение всех игроков, чей ранг выше или равен 10<p>В отличие от ADO.NET, тут будет получена не строка из таблицы, а сразу объекты, которые можно будет тут же использовать без предварительной подготовки.</p>
29
var players = db.Players.Where(p => p.Rank >= 10); //Получение всех игроков, чей ранг выше или равен 10<p>В отличие от ADO.NET, тут будет получена не строка из таблицы, а сразу объекты, которые можно будет тут же использовать без предварительной подготовки.</p>
30
<p>Вот как выглядит редактирование строк в Entity Framework:</p>
30
<p>Вот как выглядит редактирование строк в Entity Framework:</p>
31
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}"); }<p>Вот что будет выведено в результате работы такого кода:</p>
31
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}"); }<p>Вот что будет выведено в результате работы такого кода:</p>
32
<p>Никнейм игрока был успешно изменён. Теперь можно попробовать удалить эту сущность из базы данных.</p>
32
<p>Никнейм игрока был успешно изменён. Теперь можно попробовать удалить эту сущность из базы данных.</p>
33
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!"); } }<p>Тут уже можно увидеть, что проверяется, не равен ли объект null, потому что иначе будет вызвано исключение NullReferenceException.</p>
33
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!"); } }<p>Тут уже можно увидеть, что проверяется, не равен ли объект null, потому что иначе будет вызвано исключение NullReferenceException.</p>
34
<p>Вот каким будет вывод:</p>
34
<p>Вот каким будет вывод:</p>
35
<p>Entity Framework позволяет значительно сократить код работы с базами данных. При этом он предоставляет большие возможности. Например, можно использовать:</p>
35
<p>Entity Framework позволяет значительно сократить код работы с базами данных. При этом он предоставляет большие возможности. Например, можно использовать:</p>
36
<ul><li>foreign keys;</li>
36
<ul><li>foreign keys;</li>
37
<li>связи one-to-one, one-to-many и many-to-many;</li>
37
<li>связи one-to-one, one-to-many и many-to-many;</li>
38
<li>параметризацию запросов;</li>
38
<li>параметризацию запросов;</li>
39
<li>хранимые процедуры.</li>
39
<li>хранимые процедуры.</li>
40
</ul><p>Однако стоит учитывать, что EF выступает прослойкой между приложением и базой данных, поэтому может ухудшаться производительность. Для небольших проектов это допустимо, но если программа должна работать под большой нагрузкой, то лучше использовать чистый ADO.NET.</p>
40
</ul><p>Однако стоит учитывать, что EF выступает прослойкой между приложением и базой данных, поэтому может ухудшаться производительность. Для небольших проектов это допустимо, но если программа должна работать под большой нагрузкой, то лучше использовать чистый ADO.NET.</p>
41
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
41
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>