Перейти к содержанию

Магазин на Asp.Net Core MVC EF. Часть 3

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Загрузка...

[ Полезный рекламный блок ]

Попробуйте свои силы в игре, где ваши навыки программирования на C# станут решающим фактором. Переходите по ссылке 🔰.


В этой статье, мы продолжим писать магазин на Asp.Net Core и Entity Framework Core. Во второй части мы добавили средства для модификации и удаления данных в БД. Для ознакомления со второй частью, перейдите по ссылке.

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

Магазин на Asp.Net Core MVC EF. Часть 3

Подготовительные шаги

Добавление отношения в модель данных

Создание отношения

Обновление контекста и создание хранилища

Создание и применение миграции

Создание контроллера и представления

Заполнение базы данных категориями

Работа со связанными данными

Выбор категории для товара

Добавление поддержки для заказов

Создание хранилища и подготовка базы данных

Создание и применение миграции

Создание контроллеров и представлений

Сохранение данных заказа

Итог

Подготовительные шаги

В рамках подготовки мы консолидируем процесс создания и редактирования объектов Product в единственном представлении. В следующем коде объединяем методы действий контроллера Home, добавляющие или обновляющие объекты Product, и удаляем действия, которые выполняли массовые обновления:

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

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

Запустив приложение, вы увидите следующее содержимое:

интернет магазин c#

Выполните удаление всех данных из таблицы.

Добавление отношения в модель данных

В настоящий момент каждый объект Product создается со значением свойств Category, которое имеет тип string. В реальном проекте вопрос лишь в том, сколько времени пройдет до ситуации, когда из-за опечатки товар будет помещен в неподходящую категорию. Во избежание проблемы подобного рода данные приложения можно нормализировать с использованием отношений, в итоге сокращая дублирование и гарантируя безопасность.

Добавление класса модели данных

Отправной точкой станет создание нового класса модели данных. Добавьте в папку Models файл по имени Category.cs и определите в нем класс, как показано в следующем коде:

Класс Category представляет категорию товаров. Свойство Id содержит первичный ключ, а значения для свойств Name и Description будут предоставлены пользователем при создании новой категории и ее сохранении в БД.

Создание отношения

На следующем шаге создается отношение между двумя классами модели данных, что делается путем добавления свойств к одному из классов. В любом отношении между данными один из классов известен как зависимая сущность и именно к нему добавляются свойства. Чтобы выяснить, какой класс является зависимой сущностью, задайте себе вопрос, объект какого из типов не может существовать без другого. В случае приложения GameStore категория способна существовать, даже не имея в себе товаров, но каждый товар должен принадлежать какой-нибудь категории — и это значит, что в такой ситуации зависимой сущностью оказывается класс Product. Добавьте в класс Product два свойства, которые создают отношение с классом Category:

Первым здесь добавлено свойство по имени СаtegoryId, являющееся примером свойства внешнего ключа, которое инфраструктура Entity Framework Core будет при­ менять для отслеживания отношения за счет присваивания ему значения первичного ключа, идентифицирующего объект Category. Имя свойства внешнего ключа состоит из имени класса плюс имя свойства первичного ключа, давая в результате Categoryld.

Второе свойство заменяет существующее свойство Category и представляет собой пример навигационного свойства. Инфраструктура Eпtity Framework Core будет заполнять это свойство объектом Саtegory. который идентифицируется свойством внешнего ключа, что делает его более подходящим для работы с данными в БД.

Обновление контекста и создание хранилища

Для обеспечения доступа к объектам Category добавьте в класс контекста БД свойство DbSet<T>:

Новое свойство следует тому же самому шаблону, что и существующее свойство: оно объявлено как свойство public с конструкциями get и set. а возвращает экземпляр DbSet<T>, где Т — класс, который нужно хранить в БД.

Когда модель данных расширяется, вы можете снабдить остальной код в приложении доступом к новым типам данных, добавив члены к существующему классу хранилища или создав новый такой класс. Для приложения GameStore давайте создадим отдельное хранилище, просто чтобы продемонстрировать, как это делается.

В папку Interfaces, добавьте интерфейс ICategory, со следующим содержимым:

В папку Repository, добавьте класс CategoryRepository, со следующим содержимым:

Мы создали интерфейс хранилища и класс реализации, по аналогии, как и с классом Product.

Зарегистрируйте хранилище и его реализацию в классе Program для применения со средством внедрения зависимостей:

Создание и применение миграции

Инфраструктура Entity Framework Core не сможет сохранять объекты Category до тех пор, пока БД не будет обновлена для соответствия изменениям, внесенным в модель данных. Чтобы обновить БД, потребуется создать и применить к ней миграцию.

Для создания миграции в окне Package Manager Console введите следующую команду:

asp.net core migration init

Для выполнения инструкций миграции, в окне Package Manager Console выполните команду:

Первая команда создает новую миграцию по имени Categories, которая будет содержать команды, требующиеся для подготовки БД к хранению новых объектов. Вторая команда выполняет такие команды для обновления БД.

Создание контроллера и представления

Мы создали обязательное отношение между классами Product и Category, т.е. каждый объект Product должен быть ассоциирован с объектом Category. При отношении такого вида полезно снабжать пользователя средствами для управления объектами Category в БД. Добавьте в папку Controllers файл класса по имени CategoriesController.cs и поместите в него следующий код:

Контроллер Categories принимает в своем конструкторе объект хранилища для доступа к данным категорий и определяет действия, которые поддерживают запра­шивание БД, а также создание, обновление и удаление объектов Category. Чтобы снабдить контроллер представлением, создайте папку Views/Categories и добавьте в нее файл по имени Index.cshtml со следующим содержимым:

Представление Index предлагает единый интерфейс для управления категориями и поручает создание и редактирование объектов частичному представлению. Чтобы создать частичное представление, добавьте в папку Views/Categories файл по имени CategoryEditor.cshtml и поместите в него следующие содержимое:

Для облечения перемещения по приложению в файл ViewsShared_Layout.cshtml, добавьте следующий код:

Запустите приложение и проверьте его работу.

adding items c#

Заполнение базы данных категориями

Запустите приложение и добавьте 3 любые категории на странице “Категории”:

asp.net core add category

Работа со связанными данными

Инфраструктура Entity Framework Соге игнорирует отношения, если только они явно не включаются в запросы. Это означает, что навигационные свойства, такие как свойство Category, определенное в классе Product, по умолчанию будут оставляться равными null. Расширяющий метод Include() применяется для сообщения инфраструктуре EF о необходимости заполнения навигационного свойства связанными данными.

Перейдем в класс ProductRepository и изменим его реализацию, включив объект категории:

Метод Include() определен в пространстве имен Microsoft.Entity FrameworkCore и принимает лямбда-выражение, выбирающее навигационное свойство, которое желательно включить в запрос. Метод Find(), применяемый для метода GetProduct(),не может использоваться с методом Include(), поэтому он заменен методом First(), который приводит к тому же самому эффекту. Результат внесенных изменений заключается в том, что инфраструктура Entity Framework Core будет заполнять навигационное свойство Product.Саtegory для объектов Product, созданных свойством Products и методом GetProduct().

Обратите внимание на изменения в методе UpdateProduct(). Во-первых, исходные данные запрашиваются напрямую, а не через метод GetProduct(), потому что загружать связанные данные при выполнении обновления нежелательно. Во-вторых, закомментирован оператор, устанавливающий свойство Category, и добавлен оператор, который взамен устанавливает свойство Саtegoryid. Установка свойства внешнего ключа – все, что необходимо инфраструктуре Entity Framework Core для обновления отношения между двумя объектами в БД.

Выбор категории для товара

Обновим контроллер Home, чтобы он имел доступ к данным Category через хранилище и передавал их своему представлению. Это позволит представлению предложить выбор из полного набора категорий при редактировании или создании объекта Product:

Чтобы предоставить пользователю возможность выбора одной из категорий при создании или редактировании объекта Product, добавим в представление UpdateProduct элемент select:

В разметку включен элемент-заполнитель option на случай, если представление используется для создания нового объекта Product, и предусмотрено выражение Razor для применения атрибута selected, если текущий объект редактируется. Осталось лишь обновить представление Index, чтобы проследовать по навигационному свойству и отобразить для каждого объекта Product название выбранной категории. Перейдем в Home / Index.cshtml и изменим содержимое:

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

entity framework add product

После создания каждого объекта инициируется действие Index для отображения результатов, которое заставляет инфраструктуру Entity Framework Core запросить в БД данные Product и связанные с ними объекты Category. Вы можете увидеть, как он транслируется в SQL-зaпpoc, просмотрев сгенерированные приложением журнальные сообщения:

Инфраструктура Entity Framework Core использует внешний ключ для запрашивания данных, которые необходимы для создания объектов Category, связанных с объектами Product, и применяет внутреннее соединение для объединения данных из таблиц Products и Categories.

P.S. Если вы удалите объект Category, то связанные с ним объекты Product, также удалятся, что является стандартной конфигурацией для обязательных отношений.

Добавление поддержки для заказов

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

Создание классов модели данных

Начнем с добавления в папку Models файла по имени Order.cs со следующим содержимым:

Класс Order имеет свойства, которые хранят имя и адрес покупателя, а также признак, доставлены ли товары. Есть также навигационное свойство, обеспечивающее доступ к связанным объектам OrderLine, которые будут представлять отдельные выбранные товары.

Для создания класса OrderLine добавьте в папку Models файл по имени OrderLine.cs со следующим содержимым:

Каждый объект OrderLine связан с объектами Order и Product и имеет свойство, которое отражает, сколько товара покупатель заказал. Чтобы обеспечить удобный доступ к данным Order, добавим в класс контекста ApplicationContext, следующие свойства:

Создание хранилища и подготовка базы данных

Для предоставления согласованного доступа к новым данным остальному коду приложения добавьте в папку Interfaces файл по имени IOrder.cs со следующим содержимым:

Добавьте в папку Repository файл по имени OrderRepository.cs со следующим содержимым:

Реализация хранилища следует шаблону, принятому для других хранилищ, и ради простоты не задействует средство обнаружения изменений. Обратите внимание на применение методов Include() и Theninclude() для навигации по модели данных и добавления в запросы связанных данных.

Добавьте в класс Program оператор, чтобы система внедрения зависимостей распознавала зависимости от интерфейса IOrderRepository с использованием кратковременных объектов OrderRepository:

Создание и применение миграции

Инфраструктура Entity Framework Core не сможет сохранять объекты Order до тех пор, пока БД не будет обновлена для соответствия изменениям, внесенным в модель данных. Чтобы обновить БД, потребуется создать и применить к ней миграцию.

Для создания миграции в окне Package Manager Console введите следующую команду:

migration ef c#

Для выполнения инструкций миграции, в окне Package Manager Console выполните команду:

Первая команда создает новую миграцию по имени Orders, которая будет содержать команды, требующиеся для подготовки БД к хранению новых объектов. Вторая команда выполняет такие команды для обновления БД.

Текущая структура применённых миграций:

migration history

Текущая структура проекта:

asp.net core project structure

Создание контроллеров и представлений

Весь связующий код Entity Framework Core для работы с объектами Order на месте; следующий шаг предусматривает добавление средств MVC, которые позволят создавать и управлять экземплярами. Добавьте в папку Controllers контроллер по имени OrdersController.cs, со следующим содержимым:

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

Операторы LINQ в методе действия EditOrder() могут выглядеть запутанными, но они осуществляют подготовку данных OrderLine, чтобы иметь один объект OrderLine для каждого объекта Product, даже если ранее этот товар не выбирался.

Таким образом, для нового заказа свойство ViewBag.Lines будет заполняться последовательностью объектов OrderLine, соответствующих каждому объекту Product в БД, с установленными в 0 свойствами Id и Quantity. Когда объект сохраняется в БД, нулевое значение Id будет указывать, что объект является новым, и сервер баз данных присвоит ему новый уникальный первичный ключ.

Для существующих заказов свойство ViewBag.Lines будет заполняться объектами OrderLine, прочитанными из БД и дополнительными объектами с нулевыми свойствами Id для остальных товаров.

Далее необходимо создать представление, которое будет отображать список всех объектов в БД. Добавьте папку Views / Orders и поместите в нее файл по имени Index.cshtml со следующим содержимым:

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

Чтобы снабдить приложение представлением для создания или редактирования заказа. добавьте в папку Views / Orders файл по имени EditOrder.cshtml, со следующим содержимым:

Представление EditOrder предлагает пользователю форму с элементами input для свойств, определенных в классе Order, и элементами для всех объектов Product в БД, которые будут заполняться заказанным количеством при редактировании существующих объектов.

Для облегчения доступа к заказам, добавим ссылку в меню, для этого изменим содержимое Views / Shared / _Layout.cshtml, следующим образом:

Запустите приложение, убедитесь, что форма заказа отображается корректно:

asp.net core mvc orders

Сохранение данных заказа

Щелчок на кнопке Сохранить не приводит к сохранению каких-либо данных, потому что метод AddOrUpdateOrder() остался незавершенным. Перейдем в контроллер Orders и допишем данный метод:

Операторы в методе действия полагаются на удобную функциональную особенность Entity Framework Core: в случае передачи объекта Order методу AddOrder() или UpdateOrder() хранилища инфраструктура Entity Framework Core сохранит не только этот объект Order, но и связанные с ним объекты OrderLine. Указанная особенность может не выглядеть важной, но она упрощает процесс, который иначе потребовал последовательности тщательно скоординированных обновлений.

Чтобы просмотреть генерируемые SQL-команды. запустите приложение и выполните добавление одного заказа, с 2-3-емя товарами:

Первая команда сохраняет объект Order, а вторая получает значение, назначенное первичному ключу. Далее EF используется первичный ключ объекта Order для сохранения объектов OrderLine.

Последний момент, который нужно отметить, касается следующего оператора:

Оператор исключает любой объект OrderLine. для которого не было выбрано не­ нулевое количество, кроме объектов. уже хранящихся в БД. Это гарантирует, что БД не переполнится объектами OrderLine, которые не являются частью какого-то заказа, но разрешает вносить изменения в ранее сохраненные данные.

После сохранения данных отобразится сводка по заказу:

asp.net core order details

Итог

В главе модель данных GameStore была расширена за счет добавления новых классов и создания отношений между ними. Вы узнали, как запрашивать связанные данные, каким образом выполнять обновления. В следующей главе будет показано, каким образом приспособить части MVC и Entity Framework Core к работе с крупными объемами данных.

На этом статья «Магазин на Asp.Net Core MVC EF», подошла к концу, надеюсь вам было интересно. Вы можете скачать исходный код в моем репозитории — Github.

Поделитесь вашим опытом в комментариях, какой был ваш первый проект, магазин на Asp.Net Core MVC EF или что-то другое?

Так же вам может быть интересна предыдущая статья:

Генерация кода Captcha в ASP.NET Core

Вы начинающий программист, который хочет изучить все тонкости языка C#?

Пройдите наш тест на 13 вопросов, чтобы узнать, как много вы знаете на самом деле!

C# Braincheck


Вы хотите научится писать код на языке программирования C#?

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

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

  • Доступ к пройденному материалу
  • Тематические статьи
  • Библиотека книг
  • Онлайн тестирование
  • Общение в закрытых группах

https://dijix.com.ua

Живи в своем мире, программируй в нашем.


 

Опубликовано в рубрикеAsp.Net Core
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x