HTML Diff
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 &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --&gt; &lt;section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /&gt; &lt;/configSections&gt; &lt;startup&gt; &lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /&gt; &lt;/startup&gt; &lt;entityFramework&gt; &lt;defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /&gt; &lt;providers&gt; &lt;provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /&gt; &lt;/providers&gt; &lt;/entityFramework&gt; &lt;/configuration&gt;<p>В него вносится информация о СУБД. Для этого после элемента<em>&lt;configSections&gt;</em>добавляем следующее:</p>
14 &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --&gt; &lt;section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /&gt; &lt;/configSections&gt; &lt;startup&gt; &lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /&gt; &lt;/startup&gt; &lt;entityFramework&gt; &lt;defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /&gt; &lt;providers&gt; &lt;provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /&gt; &lt;/providers&gt; &lt;/entityFramework&gt; &lt;/configuration&gt;<p>В него вносится информация о СУБД. Для этого после элемента<em>&lt;configSections&gt;</em>добавляем следующее:</p>
15 &lt;connectionStrings&gt; &lt;add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=GameDB;Integrated Security=True;" providerName="System.Data.SqlClient"/&gt; &lt;/connectionStrings&gt;<p>Отсюда фреймворк будет брать<em>connectionString</em>. В этом примере приложение будет подключаться к <em>SQLEXPRESS</em>, но можно использовать и <em>localdb</em>. При этом достаточно указать любое название самой базы данных: если её не существует, EF создаст её сам. То же самое касается и всех таблиц.</p>
15 &lt;connectionStrings&gt; &lt;add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=GameDB;Integrated Security=True;" providerName="System.Data.SqlClient"/&gt; &lt;/connectionStrings&gt;<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&lt;Player&gt; 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&lt;Player&gt; 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 =&gt; p.Rank &gt;= 10); //Получение всех игроков, чей ранг выше или равен 10<p>В отличие от ADO.NET, тут будет получена не строка из таблицы, а сразу объекты, которые можно будет тут же использовать без предварительной подготовки.</p>
29 var players = db.Players.Where(p =&gt; p.Rank &gt;= 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 =&gt; p.Id == 2); //Получение игрока с Id, равным 2 players.FirstOrDefault().Nickname = "New nick"; //Так как данные вносятся в список, то нужно получить первый элемент db.SaveChanges(); //Сохранение изменений } using (PlayerContext db = new PlayerContext()) //Чтобы проверить, произошли ли изменения, новые данные получаются в другом контексте { var players = db.Players.Where(p =&gt; 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 =&gt; p.Id == 2); //Получение игрока с Id, равным 2 players.FirstOrDefault().Nickname = "New nick"; //Так как данные вносятся в список, то нужно получить первый элемент db.SaveChanges(); //Сохранение изменений } using (PlayerContext db = new PlayerContext()) //Чтобы проверить, произошли ли изменения, новые данные получаются в другом контексте { var players = db.Players.Where(p =&gt; 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 =&gt; 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 =&gt; 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 =&gt; 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 =&gt; 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>