Как подключить entity framework к проекту с
Перейти к содержимому

Как подключить entity framework к проекту с

  • автор:

Как подключить entity framework к проекту с

Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core

Последнее обновление: 24.10.2018

Чтобы непосредственно начать работать с Entity Framework, создадим первое приложение. Для этого нам нужна будет, во-первых, среда разработки. В качестве среды разработки выберем Visual Studio 2017.

В окне создания проекта в левой части выберем секцию Visual C#->Windows Desktop и в центральной части окна в качестве типа проекта выберем Console App (.NET Framework) .

Создание проекта для Entity Framework 6

Теперь первым делом добавим новый класс, который будет описывать данные. Пусть наше приложение будет посвящено работе с пользователями. Поэтому добавим в проект новый класс User:

public class User < public int Id < get; set; >public string Name < get; set; >public int Age < get; set; >>

Это обычный класс, который содержит некоторое количество автосвойств. Каждое свойство будет сопоставляться с отдельным столбцом в таблице из бд.

Надо отметить, что Entity Framework при работе с Code First требует определения ключа элемента для создания первичного ключа в таблице в бд. По умолчанию при генерации бд EF в качестве первичных ключей будет рассматривать свойства с именами Id или [Имя_класса]Id (то есть UserId). Если же мы хотим назвать ключевое свойство иначе, то нам нужно будет внести дополнительную логику на c#.

Теперь для взаимодействия с бд нам нужен контекст данных. Это своего рода посредник между бд и классами, описывающими данные. Но, у нас по умолчанию еще не добавлена библиотека для EF. Чтобы ее добавить, нажмем на проект правой кнопкой мыши и выберем в контекстном меню Manage NuGet Packages.

Добавление Entity Framework через NuGet

Затем в появившемся окне управления NuGet-пакетами в окне поиска введем слово «Entity» и выберем пакет собственно Entity Framework и установим его:

Установка Entity Framework

После установки пакета добавим в проект новый класс UserContext:

using System; using System.Collections.Generic; using System.Data.Entity; namespace FirstEF6App < class UserContext : DbContext < public UserContext() :base("DbConnection") < >public DbSet Users < get; set; >> >

Основу функциональности Entity Framework составляют классы, находящиеся в пространстве имен System.Data.Entity. Среди всего набора классов этого пространства имен следует выделить следующие:

  • DbContext : определяет контекст данных, используемый для взаимодействия с базой данных.
  • DbModelBuilder : сопоставляет классы на языке C# с сущностями в базе данных.
  • DbSet/DbSet : представляет набор сущностей, хранящихся в базе данных

В любом приложении, работающим с БД через Entity Framework, нам нужен будет контекст (класс производный от DbContext) и набор данных DbSet, через который мы сможем взаимодействовать с таблицами из БД. В данном случае таким контекстом является класс UserContext.

В конструкторе этого класса вызывается конструктор базового класса, в который передается строка «DbConnection» — это имя будущей строки подключения к базе данных. В принципе мы можем не использовать конструктор, тогда в этом случае строка подключения носила бы имя самого класса контекста данных.

И также в классе определено одно свойство Users, которое будет хранить набор объектов User. В классе контекста данных набор объектов представляет класс DbSet . Через это свойство будет осуществляться связь с таблицей объектов User в бд.

И теперь нам надо установить подключение к базе данных. Для установки подключения обычно используется файл конфигурации приложения. В проектах для десктопных приложений файл конфигурации называется App.config (как в нашем случае), в проектах веб-приложений — web.config . В нашем случае, поскольку у нас консольное приложение, это файл App.config . После добавления Entity Framework он выглядит примерно следующим образом:

Содержимое файла в каждом конкретном случае может отличаться. Но в любом случае после добавления EntityFramework в проект в нем будет содержаться элемент configSections. И после закрывающего тега добавим следующий элемент:

Все подключения к источникам данных устанавливаются в секции connectionStrings , а каждое отдельное подключение представляет элемент add . В конструкторе класса контекста UserContext мы передаем в качестве названия подключения строку «DbConnection», поэтому данное название указывается в атрибуте name=»DBConnection» .

Настройку строки подключения задает атрибут connectionString . В данном случае мы устанавливаем название базы данных, с которой будем взаимодействовать — userstore.

Теперь перейдем к файлу Program.cs и изменим его содержание следующим образом:

using System; namespace FirstEF6App < class Program < static void Main(string[] args) < using(UserContext db = new UserContext()) < // создаем два объекта User User user1 = new User < Name = "Tom", Age = 33 >; User user2 = new User < Name = "Sam", Age = 26 >; // добавляем их в бд db.Users.Add(user1); db.Users.Add(user2); db.SaveChanges(); Console.WriteLine("Объекты успешно сохранены"); // получаем объекты из бд и выводим на консоль var users = db.Users; Console.WriteLine("Список объектов:"); foreach(User u in users) < Console.WriteLine(". - ", u.Id, u.Name, u.Age); > > Console.Read(); > > >

Так как класс UserContext через родительский класс DbContext реализует интерфейс IDisposable , то для работы с UserContext с автоматическим закрытием данного объекта мы можем использовать конструкцию using .

В конструкции using создаются два объекта User и добавляются в базу данных. Для их сохранения нам достаточно использовать метод Add : db.Users.Add(user1)

Чтобы получить список данных из бд, достаточно воспользоваться свойством Users контекста данных: db.Users

В результате после запуска программа выведет на консоль:

Объекты успешно сохранены Список объектов: 1.Tom - 33 2.Sam - 26

Таким образом, Entity Framework обеспечивает простое и удобное управление объектами из базы данных. При том в данном случае нам не надо даже создавать базу данных и определять в ней таблицы. Entity Framework все сделает за нас на основе определения класса контекста данных и классов моделей. И если база данных уже имеется, то EF не будет повторно создавать ее.

Наша задача — только определить модель, которая будет храниться в базе данных, и класс контекста. Поэтому данный подход называется Code First — сначала пишется код, а потом по нему создается база данных и ее таблицы.

Возникает вопрос, а где же находится БД? Чтобы физически увидеть базу данных, мы можем подключиться к ней из Visual Studio через окно View->SQL Server Object Explorer . После этого мы можем увидеть в SQL Server Object Explorer созданную базу данных, посмотреть ее строение, таблицы, открыть и даже изменить данные в таблицах:

SQL Server Object Explorer в Visual Studio

Физически база данных по умолчанию будет располагаться в папке пользователя, в частности, у меня она размещена в каталоге C:\Users\Eugene\ , только к ее названию буде добавляться стандартное расширение mdf — userstore.mdf.

Настройка подключения к базе данных

При работе с Entity Framework во всех предыдущих примерах мы полагались на соглашения Code-First по автоматическому определению подключения к базе данных. По умолчанию, Code-First создает базу данных на локальном сервере .\SQLEXPRESS, используя полное имя класса контекста для имени базы данных (например, пространство имен + имя класса). Для примера нашего проекта это означает, что Code-First создаст базу данных с именем CodeFirst.SampleContext. Зачастую это поведение необходимо переопределить, в частности мы передавали имя базы данных MyShop в конструкторе класса контекста. В этой статье содержится подробное описание настроек имени базы данных и подключения к ней.

Использование конфигурационного файла приложения

Самым простым способом управления подключением к базе данных является использование конфигурационного файла приложения. В файле конфигурации можно переопределить базовые соглашения Code-First и точно указать строку подключения к базе данных. Этот подход особенно полезен, если вы хотите изменить строку подключения в вашем контексте, чтобы указать подключение к удаленной (не локальной) базе данных при развертывании приложения.

В приложениях ASP.NET конфигурационным файлом является файл Web.config, в приложениях другого типа – App.config. При использовании нескольких проектов в одном решении можно допустить ошибку с правильным выбором конфигурационного файла. Например, в нашем приложении сущностная модель находится в проекте библиотеки классов CodeFirst, а непосредственно с данными мы работаем в проекте веб-приложения ASP.NET. Возможно вам покажется правильным, разместить настройки подключения в файле App.config проекта CodeFirst. Однако это является неправильным решением. Entity Framework настраивает базу данных при создании объекта контекста, а не при его объявлении. В примерах, приводившихся ранее, мы использовали объект контекста в коде веб-форм, поэтому настройки строки подключения нужно указывать в файле Web.config веб-приложения ASP.NET.

Благодаря такому подходу обеспечивается возможность многоразового использования модели данных. В каждом проекте, где мы ссылаемся на проект CodeFirst, мы можем указать свою строку подключения, т.е. одна модель будет работать с разными базами данных.

Для указания строки подключения используется раздел конфигурации connectionString. По умолчанию, строка подключения должна иметь то же имя, что и файл контекста, при этом можно указать как полное имя так и краткое (т.е SampleContext или CodeFirst.SampleContext). Благодаря этому, Entity Framework автоматически найдет нужную строку подключения в файле конфигурации и использует ее. В примере ниже показано определение строки подключения:

Запустите этот пример и убедитесь, что Code-First создаст новую базу данных с именем MyShop2 для текущей модели. Если вы прорабатывали примеры из предыдущих статей, то пока удалите вызов конструктора базового класса из класса контекста. В результате будет создана следующая база данных:

Настройка подключения из конфигурационного файла

Настройка подключения в конструкторе класса контекста

Выше вы видели, как задать строку подключения из файла конфигурации так, что контекст будет использовать ее автоматически благодаря соглашениям Code-First. Теперь давайте посмотрим на некоторые способы управления подключением к базе данных из кода.

Класс DbContext помимо конструктора по умолчанию включает в себя несколько перегруженных версий конструкторов. Если вы используете один из этих конструкторов, Code-First не будет использовать соглашения для автоматического поиска строки подключения. Самая простая версия конструктора класса DbContext принимает один строковый параметр. Давайте посмотрим как использовать этот конструктор из производного класса:

public class SampleContext : DbContext < public SampleContext() : base("MyShop") < >public DbSet Customers < get; set; >>

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

Обратите внимание, что в этом примере мы вызываем перегруженный конструктор класса DbContext из конструктора по умолчанию производного класса SampleContext. При таком подходе к проектированию, когда вы создаете объект контекста в вашем приложении, строка подключения будет автоматически выбираться из конструктора по умолчанию класса SampleContext. Иногда бывает необходимо указать строку подключения при создании объекта контекста. Для этого можно добавить перегруженный конструктор в класс контекста с вызовом перегруженного конструктора DbContext:

public class SampleContext : DbContext < public SampleContext() < >public SampleContext(string dbNameOrConnection) : base(dbNameOrConnection) < >// . >

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

protected void Page_Load(object sender, EventArgs e)

В этом примере извлекаются данные всех покупателей из таблицы Customers базы данных MyShop2, т.к. мы указали полную строку подключения к этой базе данных. Если в данном примере вы создадите объект контекста с использованием конструктора по умолчанию:

SampleContext context = new SampleContext();

то Code-First использует соглашения по автоматическому поиску строки подключения, и, если не найдет строку подключения с именем SampleContext или CodeFirst.SampleContext, то попытается подключиться к базе данных с именем CodeFirst.SampleContext.

У вас также может возникнуть вопрос, как явно передать конструктору класса контекста имя строки подключения, если оно не соответствует имени класса контекста. Для этого можно использовать укороченную строку подключения с единственным параметром name:

public class SampleContext : DbContext < public SampleContext() : base("name=MyConnectionStringName") < >// . > 

Теперь Code-First будет искать в конфигурационном файле строку подключения с именем MyConnectionStringName.

Повторное использование подключения к базе данных

Одна из перегруженных версий конструктора DbContext принимает объект подключения DbConnection из пространства имен System.Data.Common. Использование этого объекта может быть полезно, если вы хотите указать в нескольких объектах контекста один и тот же объект подключения и не хотите каждый раз указывать имя базы данных или строки подключения. Т.е. объект DbConnection может храниться в определенном месте приложения и вы можете ссылаться на него всякий раз, когда создаете объект контекста. Ниже показан пример:

using System.Data.Entity; using System.Data.Entity.ModelConfiguration; using System.Data.Common; namespace CodeFirst < // Определяет строку подключения к бд MyShop public class DbConnectionToMyShop : DbConnection < public DbConnectionToMyShop() < this.ConnectionString = ". "; >> public class SampleContext : DbContext < public SampleContext() : base(new DbConnectionToMyShop(), contextOwnsConnection: false) < >public SampleContext(DbConnection connection) : base(connection, false) < >// . > >

В этом примере мы создали класс DbConnectionToMyShop, для подключения к базе данных MyShop. Объект этого класса передается в конструкторе по умолчанию класса контекста. Мы также создали для удобства перегруженный конструктор — в коде приложения вы можете просто передать нужный объект подключения. Классы подключений можно определить в одном файле и затем использовать повсеместно в приложении. Второй параметр в этом конструкторе contextOwnsConnection указывает, нужно ли очищать объект подключения при удалении объекта контекста.

Настройка соглашений подключения в Code-First

Последним способом управления подключением к базе данных, является замена соглашений, которые использует Code-First. Соглашения по конфигурации подключения определяются с помощью интерфейса IDbConnectionFactory. Вы можете реализовать этот интерфейс и передать его методу SetDefaultConnectionFactory() класса DbConfiguration, переопределив тем самым соглашения по умолчанию Code-First.

Соглашения по умолчанию реализует класс SqlConnectionFactory из пространства имен System.Data.Entity.Infrastructure. Поведение по умолчанию определяет, что поставщиком базы данных будет поставщик SQL Server (сборка System.Data.SqlClient), имя сервера — .\SQLEXPRESS, а для доступа к серверу используется Windows-аутентификация (сервер доступен для текущего пользователя системы). Вы можете переопределить данные соглашения, например, для того, чтобы явно указать Entity Framework что вы хотите работать с поставщиком MySQL.

В примере ниже показано, как переопределить эти соглашения, используя класс конфигурации, унаследованный от DbConfiguration:

using System.Data.Entity; using System.Data.Entity.ModelConfiguration; using System.Data.Entity.Infrastructure; namespace CodeFirst < // Класс конфигурации public class MyDbConfig : DbConfiguration < public MyDbConfig() < SqlConnectionFactory defaultFactory = new SqlConnectionFactory("Server=MyDbServer;User=username;Password=12345;"); this.SetDefaultConnectionFactory(defaultFactory); >> [DbConfigurationType(typeof(MyDbConfig))] public class SampleContext : DbContext < public SampleContext() : base("MyShop") < >// . > >

В этом примере мы изменяем имя сервера, а также указываем, что для доступа к серверу должна использоваться SQL-аутентификация, на основе имени пользователя и пароля. Обратите внимание, чтобы указать классу контекста, чтобы он использовал эту конфигурацию, используется атрибут DbConfigurationType. Чтобы зарегистрировать новый класс конфигурации, в файле Web.config веб-приложения нужно удалить раздел defaultConnectionFactory:

Также вы можете установить конфигурацию для всех классов контекста в приложении и не использовать атрибут DbConfigurationType. Для этого укажите свойство codeConfigurationType раздела конфигурации entityFramework:

Здесь указывается ссылка на класс конфигурации и имя сборки, где этот класс располагается. Для настройки поставщика базы данных вы можете использовать метод SetProviderServices() класса конфигурации или использовать элементы provider разделе entityFramework файла конфигурации:

public class MyDbConfig : DbConfiguration < public MyDbConfig() < // . this.SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance); >>

В примерах выше показано использование стандартного поставщика данных SQL Server, но вы можете указать другие поставщики баз данных, которые требуются в вашем приложении (MySQL, Oracle и т.п.)

Работа с базой данных

Entity Framework представляет ORM-решение, которое позволяет автоматически связать классы языка C# с таблицами в базе данных. Entity Framework Core поддерживает большинство популярных СУБД, таких как MS SQL Server, SQLite, MySQL, Postres. В данном случае мы будем работать через Entity Framework Core с базами данных в MS SQL Server.

Детально ознакомиться с работой с Entity Framework Core можно в соответствуюшем руководстве, здесь же мы сосредоточимся прежде всего на тех моментах, которые характерны для веб-приложения ASP.NET Core.

Для работы с базами данных MS SQL Server через Entity Framework Core необходим пакет Microsoft.EntityFrameworkCore.SqlServer . По умолчанию он отсутствует в проекте, поэтому его надо добавить, например, через пакетный менеджер Nuget:

Добавление Entity Framework Core в ASP.NET Core и C#

Далее добавим в проект класс, которые будет представлять данные. Пусть он будет называться User и будет иметь следующий код:

public class User < public int Id < get; set; >public string Name < get; set; >= ""; // имя пользователя public int Age < get; set; >// возраст пользователя >

Этот класс представляет те объекты, которые будут храниться в базе данных.

Для взаимодействия с базой данных через Entity Framework Core необходим контекст данных — класс, унаследованный от класса Microsoft.EntityFrameworkCore.DbContext . Поэтому добавим в проект новый класс, который назовем ApplicationContext (название класса контекста произвольное):

using Microsoft.EntityFrameworkCore; public class ApplicationContext : DbContext < public DbSetUsers < get; set; >= null!; public ApplicationContext(DbContextOptions options) : base(options) < Database.EnsureCreated(); // создаем базу данных при первом обращении >protected override void OnModelCreating(ModelBuilder modelBuilder) < modelBuilder.Entity().HasData( new User < Name = "Tom", Age = 37 >, new User < Name = "Bob", Age = 41 >, new User < Name = "Sam", Age = 24 >); > >

Свойство DbSet представляет собой коллекцию объектов, которая сопоставляется с определенной таблицей в базе данных. То есть свойство Users будет представлять таблицу, в которой будут храниться объекты User.

Класс DbSet, как и другие типы, является ссылочным. А, начиная с C# 10 и .NET 6 автоматически применяется функциональность ссылочных nullable-типов. И переменные/свойства тех типов, которые не являются nullable, следует инициализировать некотором значением перед их использованием. Чтобы выйти из этой ситуации мы можем инициализировать свойство с помощью выражения null! , которое говорит, что данное свойство в принципе не будет иметь значение null. Потому что в реальности конструктор базового класса DbContext гарантирует, что все свойства типа DbSet будут инициализированы и соответственно в принципе не будут иметь значение null.

В конструкторе класса ApplicationContext через параметр options будут передаваться настройки контекста данных. А в самом конструкторе с помощью вызова Database.EnsureCreated() по определению модели будет создаваться база данных (если она отсутствует).

Кроме того, в методе OnModelCreating() настраивается некоторая начальная конфигурация модели. В частности, с помощью метода modelBuilder.Entity().HasData() в базу данных добавляются три начальных объекта

Конфигурация и строка подключения

Чтобы подключаться к базе данных, нам надо задать параметры подключения. Это можно сделать либо в коде C#, либо в файле конфигурации. Выберем второй способ. Для этого изменим файл appsettings.json . По умолчанию он содержит только настройки логгирования:

 < "Logging": < "LogLevel": < "Default": "Information", "Microsoft.AspNetCore": "Warning" >>, "AllowedHosts": "*" >

Теперь изменим его, добавив определение строки подключения:

< "ConnectionStrings": < "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=applicationdb;Trusted_Connection=True;" >, "Logging": < "LogLevel": < "Default": "Information", "Microsoft.AspNetCore": "Warning" >>, "AllowedHosts": "*" >

В данном случае мы будем использовать упрощенный движок базы данных LocalDB, который представляет легковесную версию SQL Server Express, предназначенную специально для разработки приложений. Об этом говорит параметр Server=(localdb)\\mssqllocaldb . Ну а сама база данных будет называться applicationdb .

Добавление контекста данных EF Core в качестве сервиса

Контекст данных, через который идет взаимодействие с базой данных, передается в приложение в качестве сервиса через механизм внедрения зависимостей. Поэтому для работы с Entity Framework Core необходимо добавить класс контекста данных в коллекцию сервисов приложения:

using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(); // получаем строку подключения из файла конфигурации string connection = builder.Configuration.GetConnectionString("DefaultConnection"); // добавляем контекст ApplicationContext в качестве сервиса в приложение builder.Services.AddDbContext(options => options.UseSqlServer(connection)); var app = builder.Build(); app.Run();

Для использования контекста данных ему надо передать строку подключения, которая выше была определена в файл конфигурации appsettings.json. Поэтому сначала считываем строку подключения под названием «DefaultConnection»:

string connection = builder.Configuration.GetConnectionString("DefaultConnection");

Для получения строки конфигурации для объекта IConfiguration, который представляет конфигурацию, определен метод расширения GetConnectionString() , в который передается название строки подключения.

Для добавления контекста данных в качестве сервиса у объекта коллекции сервисов IServiceCollection определен метод AddDbContext() , который типизируется классом контекста данных:

builder.Services.AddDbContext(options => options.UseSqlServer(connection));

Этот метод в качестве параметра принимает делегат, который настраивает подключение. В частности, с помощью вызова options.UseSqlServer() настраивается подключение к серверу MS SQL Server, а в качестве параметра в этот вызов передается строка подключения.

Обращение к базе данных

Подключив контекст данных мы можем с его помощью обращаеться к базе данных. Например, в качестве теста получим добавляемые по умолчанию данные:

using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(); string connection = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => options.UseSqlServer(connection)); var app = builder.Build(); // получение данных app.MapGet("/", (ApplicationContext db) => db.Users.ToList()); app.Run();

Поскольку контекст данных добавлен в сервисы, то мы можем его получить в обработчике конечной точки:

app.MapGet("/", (ApplicationContext db) => db.Users.ToList());

В данном случае клиенту отправляется список добавленных в БД по умолчанию объектов User в формате JSON:

Основы Entity Framework Core. Часть [0]

В этой части будет кратко рассказано о технологии Entity Framework Core, а также её установки в свой проект.

Кратко о технологии

Общая цель EF — предоставить возможность взаимодействия с данными из реляционных баз данных с использованием объектной модели, которая отображается напрямую на бизнес-объекты в создаваемых приложениях. Например, вместо того, чтобы трактовать пакет данных как коллекцию строк и столбцов, вы можете оперировать с коллекцией строго типизированных объектов, называемых сущностями. Такие сущности хранятся в специализированных классах коллекций, поддерживающих LINQ, что позволяет выполнять операции доступа к данным в коде С#.

Entity Framework Core (также известная как EF Core) пред­ставляет собой пакет объектно-реляционного отображения (object-relational mapping — ОRМ) производства Microsoft, который позволяет приложениям .NET Core хранить данные в реляционных базах данных. Entity Framework Core решает одну основную задачу: сохранение объектов .NET в базе данных (БД) и извлечение их в более позднее время.

Более подробно можете почитать на здесь и здесь.

Создание проекта

Для начала создадим консольное приложение в Visual Studio 2022. Как вариант, это можно сделать сразу через консоль:

dotnet new sln -n EntityFrameworkBase #создаем проект dotnet new console -lang c# -n ChapterZero -o .\ChapterZero -f net6.0 #создаем решение dotnet sln .\EntityFrameworkBase.sln add .\ChapterZero #прикрепляем к проекту решение

Или запускайте Visual Studio и выполняйте пошагово действия, которые показаны ниже:

  1. Создаем новый проект.

Создать новый проект.

  1. Создаем консольное приложение.

Выбрать консольное приложение.

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

Создать решение.

После выполненных действий в обозревателе решений (Solution Explorer) должно быть отображено следующее:

Созданный проект

Установка EF Core в свой проект

Установить все нужные библиотеки можно как и выше через консоль:

dotnet add ChapterZero package Microsoft.EntityFrameworkCore.Design dotnet add ChapterZero package Microsoft.EntityFrameworkCore.SqlServer dotnet add ChapterZero package Microsoft.EntityFrameworkCore

Или в Visual Studio через NuGet Package Manager. Процесс показан ниже:

  1. Переходим в Tools / NuGet Package Manager / Manage NuGet Packages for Solution.

Переходим в Manage NuGet Packages

  1. Переходим в Browse и ищем Microsoft.EntityFrameworkCore.

  1. Устанавливаем в проект.

Для Microsoft.EntityFrameworkCore.SqlServer и Microsoft.EntityFrameworkCore.Design повторить тоже самое. После установки всех нужных компонентов при переходе во вкладку Installed должно отобразиться следующее:

На этом пока что закончим. Код проекта тут.

Спасибо вам за прочтение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *