Entity framework как подключить

Обновлено: 05.07.2024

Во-первых, определим доменную модель, то есть что мы будем хранить в базе данных. Например, на нашем сайте пользователи смогут публиковать и редактировать статьи. Создадим подобный класс:

Во-вторых, нам понадобится так называемый контекст базы данных. Это специальный класс, который координирует работу Entity Framework между базой данных и доменной моделью нашего приложения.

В описанном выше классе важно следующее:

Далее переключаемся в класс Startup.cs, в метод ConfigureServices(). В этом месте непосредственно указывается вся конфигурация для нашего приложения, например, переадресация, кэш, сессия, маршрутизация и т.д. Нас в данном примере интересует настройки для контекста базы данных.

В коде выше мы регистрируем наш контекст и через опции указываем, что он будет подключаться к базе данных на сервере MS SQL. Далее в опциях сервера мы определяем строку подключения к базе данных. В данном примере строка подключения означает следующее:

  • источник данных - локальный SQL-сервер.
  • название базы данных - Articles.
  • Persist Security Info=False - запрещаем получение важных данных из строки подключения после открытия соединения.
  • MultipleActiveResultSets=True - также разрешаем возможность выполнения нескольких пакетов по одному соединению (MARS).
  • Trusted_Connection=True - даем возможность при соединении использовать режим Windows-аутентификации.

* в вашем проекте строка подключения конечно же может отличаться.

К данному моменту мы определили доменную модель, создали пользовательский контекст базы данных, и также настроили его для работы. Все готово для создания первой миграции. Для работы с миграциями и вообще Entity Framework можно использовать либо командное окно в Visual Studio Package Manager Console, либо стандартный PowerShell. В данном примере воспользуемся первым вариантом.

Как найти окно Package Manager Console

Добавим новую первую миграцию с помощью команды:
add-migration _initial

После создания первой миграции в проекте появится папка Migrations

После создания первой миграции в проекте появится папка Migrations

Далее применим созданную миграцию и обновим базу данных. В нашем примере база данных еще не существует, и она будет создана. Применяем команду в Package Manager Console:
update-database

На данном этапе связь между веб-приложением и сервером баз данных установлена. Чтобы было удобнее работать со статьями и совершать над ними стандартные CRUD-операции (create, read, update, delete), создадим класс-репозиторий.

Благодаря классу-репозиторию мы скрываем детали работы контекста базы данных. Теперь все манипуляции со статьями будут проходить только через репозиторий. Также зарегистрируем репозиторий как сервис в классе Startup.cs в методе ConfigureServices(), чтобы была возможность использовать его в других классах.

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

Последнее что остается - это создать соответствующие представления. Далее представлена простейшая HTML-разметка.


Курс состоит из нескольких частей:


В качестве примера будем расматривать уже ставшее классическим — приложение списка дел. Для разработки приложения я буду использовать Visual Studio 2019(в Visual Studio 2017 процесс аналогичен).

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


Назовем приложение и укажем путь к каталогу с проектом:


И выберем шаблон приложения API:


Модель

Создадим каталог Models и в новый каталог добавим первый класс TodoItem.cs, объекты которого будут описывать некоторые задачи списка дел в приложении:


В качестве СУБД мы будем использовать Sql Server, а доступ к базе данных будет осуществляться через Entity Framework Core и для начала установим фреймворк через встроенный пакетный менеджер NuGet:


Одним из подходов в работе с Entity Framework является подход «Code-First». Суть подхода заключается в том, что на основе модели приложения(в нашем случае модель представляет единственный класс — TodoItem.cs) формируется струткура базы данных(таблицы, первичные ключи, ссылки), вся эта работа происходит как бы «за кулисами» и напрямую с SQL мы не работаем. Обязательным условием класса модели является наличие поля первичного ключа, по умолчанию Entity Framework ищет целочисленное поле в имени которого присутствует подстрока «id» и формирует на его основе первичный ключ. Переопределить такое поведение можно с помощью специальных атрибутов или используя возможности Fluent API.

Главным компонентом в работе с Entity Framework является класс контекста базы данных, через который собственно и осуществляется доступ к данным в таблицах:


Базовый класс DbContext создает контекст БД и обеспечивает доступ к функциональности Entity Framework.

Для хранения данных приложения мы будем использовать SQL Server 2017 Express. Строки подключения хранятся в файле JSON под названием appsettings.json:


Далее нужно внести изменения в класс Startup.cs, добавив в метод ConfigureServices() следующий код:


Метод AddDbContext() настраивает службы, предоставляемые инфраструктурой Entity Framework Core для класса контекста базы EFTodoDBContext. Аргументом метода AddDbContext () является лямбда-выражение, которое получает объект options, конфигурирующий базу данных для класса контекста. В этом случае база данных конфигурируется с помощью метода UseSqlServer() и указания строки подключения.

Определим основные операции для работы с задачами в интерфейсе ITodoRepository:


Данный интерфейс позволяет нам не задумываться о конкретной реализации хранилища данных, возможно мы точно не определились с выбором СУБД или ORM фреймворком, сейчас это не важно, класс описывающий доступ к данным будет наследовать от этого интерфейса.
Реализуем репозиторий, который как уже сказано ранее, будет наследовать от ITodoRepository и использовать в качестве источника данных EFTodoDBContext:

Контроллер

Добавим в каталог Controllers класс TodoController.cs со следующим содержимым:

В своем конструкторе контроллер получает ссылку на объект типа ITodoRepository, но пока что инфраструктура MVC не знает, какой объект подставить при создании контроллера. Нужно создать сервис, который однозначно разрешит эту зависисмость, для этого внесем некотрые изменения в класс Startup.cs, добавив в метод ConfigureServices() следующий код:


Метод AddTransient<ITodoRepository, EFTodoRepository>() определяет сервис, который каждый раз, когда требуется экземпляр типа ITodoRepository, например в контроллере, создает новый экземпляр класс EFTodoRepository.

Полный код класса Startup.cs:

Миграции

Для того чтобы Entity Framework сгенерировал базу данных и таблицы на основе модели, нужно использовать процесс миграции базы данных. Миграции — это группа команд, которая выполняет подготовку базы данных для работы с Entity Framework. Они используются для создания и синхронизации базы данных. Команды можно выполнять как в консоли диспетчера пакетов (Package Manager Console), так и в Power Shell(Developer Power Shell). Мы будем использовать консоль диспетчера пакетов, для работы с Entity Framework потребуется установить пакет Microsoft.EntityFrameworkCore.Tools:


Запустим консоль диспетчера пакетов и выполним команду Add-Migration Initial:



В проекте появится новый каталог — Migrations, в котором будут хранится классы миграции, на основе которых и будут создаваться объекты в базе данных после выполнения команды Update-Database:


Web API готово, запустив приложение на локальном IIS Express мы можем протестировать работу контроллера.

Тестирование WebAPI

Создадим новую коллекцию запросов в Postman под названием TodoWebAPI:



Метод Create() после успешного создания задачи перенаправляет запрос на метод Get() с псевдонимом «GetTodoItem» и передает в качестве параметра Id только что созданной задачи, в результате чего в ответ на запрос мы получим созданный объект задачи в формате JSON.




На этом все, в следующей части реализуем пользовательский интерфейс с помощью JavaScript-фреймворка Angular.

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

Модуль Entity Framework Core

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

При работе с Entity Framework Core классы модели базы данных сопоставляются таблицам базы. Инкапсуляция реляционных запросов превращает работу с базами данных в «обычное» объектно-ориентированное программирование. В отличие от этого драйверы реляционного доступа, возвращают данные в виде таблицы или параметров, которые требуют дополнительной обработки.

Установка необходимых пакетов NuGet

Для использования возможностей объектно-реляционного сопоставления «объект - база данных» необходима установка приложение пакета Microsoft.EntityFrameworkCore.

Кроме этого, понадобится установка расширений SqlServerDbContextOptionsExtensions. UseSqlServer для этого необходимо в веб приложение добавить пакет Microsoft.EntityFrameworkCore. SqlServer. Это необходимо для настройки контекста и создания строк подключения с помощью построителей.

База данных для исследования


Создадим базу данных MS SQL. Для этого необходим MS SQL Server или MS SQL Server Express и MS SQL Server Management Studio. Создавать таблицы и связи между ними будем посредством инструмента управления MS SQL Server Management Studio. Базу данных назовем DBMSSQL. Добавим в базу три небольшие таблицы кратко описывающие науки и ее разделы.

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

  • PK (primary key) – первичный ключ
  • FK (foreign key) – ключ внешней связи
  • UI (unique index) – уникальный индекс

Модель базы данных

Модуль Entity Framework Core осуществляет доступ к базам данных посредством моделей. Модель – классы, определенные в соответствии таблицам базы данных. Entity Framework Core сопоставляет столбец таблицы и одноименное свойство класса соответствующей таблицы данных.

Соответственно таблицам создадим классы модели для базы данных DBMSSQL. Все таблицы в базе имеют одинаковые столбцы Id, Name, NumberViews, Uri. Чтобы уменьшить количество повторного программного кода создадим абстрактный класс с общими свойствами. Далее этот класс унаследуют классы модели базы данных.

Листинг модели базы данных:

Контекст сеанса с базой данных DBContext

Контекст баз данных представляется классом DBContext, необходимым для взаимодействия с базами данных. Объект класса производного от DBContext позволяет выполнять запросы и сохранять изменения, произведенные над свойствами экземпляров модели.

Во время взаимодействия с базой данных класс контекста наполняет классы модели информацией из таблиц базы данных. Сеанс взаимодействия контекста с базой данных краток, и состоит из одного цикла:

  • Создание объекта класса контекста
  • Получение данных (сохранение изменений)
  • Закрытие сеанса и удаление экземпляра контекста

Для наполнения классов модели информацией из базы в классе контекста необходимо определить свойства DbSet<TEntity>, где роль сущности (Entity) будут исполнять классы модели.

Класс DbSet<TEntity> - это оболочка для сущности (типа объекта таблицы базы данных), которой являются классы модели. Включение экземпляра класса DbSet<TEntity> в контекст означает, что он включен в модель Entity Framework Core. Свойства DbSet<TEntity> автоматически инициализируются при создании экземпляра класса контекста. Имена свойств, представляющих классы модели, должны быть идентичны названиям соответствующих таблиц в базе данных.

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

Листинг класса контекста для взаимодействия с базой данных DBMSSQL:

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

Реквизиты подключения к определенной базе данных, для контекста, указываются в строке подключения (connection string). Строку подключения к MS SQL Server удобно создавать с помощью построителей. Например, с помощью класса SqlConnectionStringBuilder, входящего в состав пространства имён Microsoft.Data.SqlClient (пакет Microsoft.EntityFrameworkCore.SqlServer). Таким способом создаётся синтактически правильная строка подключения к серверу базы данных.

Строка подключения отправляет серверу информацию для идентификации клиента, способе проверки клиента и выборе базы данных для последующих запросов. Разные режимы проверки подлинности пользователя требуют соответствующее содержание строки подключения.

Листинг двух вариантов строк подключения к SQL серверу:

Выполнение запросов к базе данных

Подключение к базе данных в веб приложении происходит при создании экземпляра класса контекста SqlDBContext. Экземпляр контекст создаётся в конструкторе контроллера HomeController.

После создания объекта контекста можно выполнять запросы к базе данных. В представления полученная информация передаётся в виде слабо-типизированных ViewBag и строго-типизированных объектов посредством Model.

Представление с моделью

Листинг представления с моделью:

Представление с ViewBag

Полученные данные можно передавать в представления динамическими переменными. Слаботипизированная переменная ViewBag может передавать любой объект, и что удобно, не требует приведения типов при присваивании соответствующему объекту.

В нашем случае в представление передаются списки объектов с информацией, полученной из базы данных. Путём перебора элементов списков, используя минимум кода Razor и разметки HTML, информация выводится в браузер в удобочитаемом виде.

Листинг представления с применением динамического свойства ViewBag:


Сущности (модели) - классы, отображаемые в базе данных

Добавление нового проекта ASP.NET Core Web application

Нам необходимо установить библиотеки Microsoft.EntityFrameworkCoreи Microsoft.EntityFrameworkCore.SqlServer . Это можно сделать с помощью диспетчера NuGet или окна консоли диспетчера пакетов.

Класс модели (сущности) - это класс, который Entity Framework Core использует для сопоставления с таблицей базы данных. Итак, давайте создадим нашу первую сущность, а затем объясним, как EF Core создает таблицу из созданного класса.

Давайте создадим папку Entities и внутри класса с именем Student :

Есть несколько правил, которые помогают EF Core сопоставить этот класс с таблицей базы данных, и мы собираемся объяснить весь процесс. Прежде всего, используя имя нашего класса, EF Core получает информацию, какую таблицу использовать для столбцов и сопоставлений конфигурации (как только мы создадим класс контекста, станет намного проще понять, откуда EF Core знает что).

Затем все общедоступные свойства этого класса будут сопоставлены с одноименными столбцами таблицы. Наконец, EF Core использует соглашение об именах для создания первичного ключа из свойства StudentId в таблице базы данных (позже, в разделе «Настройка нереляционных свойств», мы увидим, как это сделать).

Создание класса модели или классов модели - лишь одна часть головоломки. Чтобы в EF Core была необходимая информация о базе данных для работы, нам необходимо предоставить строку подключения, изменив файл appsettings.json .

Размещение строки подключения в файле appsettings.json - обычная практика (и мы собираемся использовать ту же практику в этой статье), потому что мы можем использовать разные файлы настроек приложения для разных сред:

  • Development.json - содержит настройки, относящиеся к среде разработки.
  • Production.json - содержит настройки, относящиеся к производственной среде.
  • appsettings.json - содержит настройки, общие для обеих сред.

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

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

Вот и все, мы можем перейти к классу контекста.

Класс контекста - еще одна важная часть приложения. Этот класс должен наследовать от базового класса DbContext , который содержит информацию и конфигурацию для доступа к базе данных. Итак, давайте создадим наш контекстный класс с именем ApplicationContext в папке Entities :

Дополнительные параметры отправляются в базовый класс DbContext через конструктор ApplicationContext с помощью параметра DbContextOptions . Наконец, мы видим свойство Student типа DbSet<Student> , и это довольно важная часть.

EF Core ищет все общедоступные свойства DbSet внутри класса контекста приложения, а затем сопоставляет их имена с именами таблиц в базе данных. Затем он входит в класс, который предоставляется в свойстве `DbSet ` (в нашем случае это класс Student ), и сопоставляет все общедоступные свойства в столбцы таблицы с одинаковыми именами и типами (StudentId, Name и Age).

Если наш класс Student имеет какие-либо ссылки на другие классы (прямо сейчас их нет, но мы создадим отношения в следующих статьях), EF Core будет использовать эти ссылочные свойства и создавать отношения в база данных.

После того, как мы закончили создание класса ApplicationContext , мы можем перейти к его регистрации.

Для этого мы собираемся открыть класс Startup.cs и изменить метод ConfigureServices :

Мы используем метод расширения AddDbContext для регистрации нашего класса ApplicationContext в контейнере IOC. Внутри метода UseSqlSrver мы предоставляем строку подключения к нашему классу контекста, а также можем предоставить дополнительные параметры (если в этом появится необходимость).

О AddDbContextPool

Вместо метода AddDbContext мы можем использовать метод AddDbContextPool. Мы можем использовать либо первый, либо второй метод, но во втором методе мы включаем пул DbContext. Это не будет создавать каждый раз новый экземпляр, но сначала проверит, есть ли доступные экземпляры в пуле, и если они есть, он будет использовать один из них.

Сейчас наш класс контекста готов к использованию с инъекцией зависимостей (DI) внутри нашего приложения. Итак, давайте добавим контроллер Values ​​(API) и изменим его:

Как вы могли заметить, мы внедряем наш класс контекста внутрь конструктора контроллера, что является обычным решением для DI.

Углубляемся в класс DbContext

Наш класс ApplicationContext в настоящее время принимает один параметр типа DbContextOptions внутри конструктора. Но мы также можем предоставить общую версию параметра DbContextOptions :

Независимо от того, используем ли мы универсальную или неуниверсальную версию параметра DbContextOptions , наше приложение будет работать одинаково. Основное отличие заключается в том, что неуниверсальную версию не рекомендуется использовать, если в нашем приложении есть несколько типов контекста, что сейчас не так.

Если мы перейдем к определению DbContext, мы увидим, что внутри у него есть три свойства:

  • База данных - это свойство отвечает за транзакции, перенос / создание базы данных и необработанные SQL-запросы (обо всем этом мы поговорим в следующих статьях).
  • ChangeTracker - это свойство используется для отслеживания состояний объектов, полученных с помощью одного и того же экземпляра контекста (это также будет рассмотрено в следующих статьях).
  • Модель - это свойство обеспечивает доступ к модели базы данных, которую EF Core использует при подключении или создании базы данных.

Мы можем использовать свойство Model для доступа к информации о каждой сущности и ее свойствах.

После установки мы можем изменить наше действие Get:

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

Читайте также: