[ Полезный рекламный блок ]
Попробуйте свои силы в игре, где ваши навыки программирования на C# станут решающим фактором. Переходите по ссылке 🔰.
У цій статті розглянемо процес побудови пагінації в стилі “Показати ще” в проєкті, який продемонструє спільне використання ASP.NET Core MVC і Entity Framework Core. Проект буде простим, але близьким до реальності, приступимо.
Створення та налаштування проекту
Щоб створити проєкт ShowMore, запустіть Visual Studio і виберіть у меню File (Файл) – New Project (Створити Проєкт). Вкажіть шаблон проекту ASP.NET Core Web Application (Веб-додаток ASP.NET Core). Введіть ShowMore, у полі Name, на наступній сторінці вкажіть Framework .Net 7.0 і натисніть кнопку Create:
Конфігурація підключення
Для початку завантажимо бібліотеку Entity Framework Core Sql Server:
Або через Package Manager Console:
1 |
Install-Package Microsoft.EntityFrameworkCore.SqlServer |
Перейдемо у файл appsettings.json і пропишемо конфігурацію підключення та логування:
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\mssqllocaldb;Database=productsStoreDb;Trusted_Connection=True;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Information" } }, "AllowedHosts": "*" } |
Рядки підключення визначаються у файлі appsettings.json, у коді вище наведено визначення рядка підключення для БД додатка GameStore. У проєкті застосовується версія LocalDB продукту SQL Server, яка спроєктована спеціально для розробників і не вимагає конфігурації або облікових даних.
Створення класу контексту даних
У забезпеченні доступу до даних у БД інфраструктура Entity Framework Core покладається на клас контексту БД. Щоб забезпечити приклад додатка контекстом, додайте папку Data, а в неї файл класу на ім’я ApplicationContext.cs з таким кодом:
1 2 3 4 5 6 7 8 |
public class ApplicationContext : DbContext { public ApplicationContext(DbContextOptions<ApplicationContext> context) : base(context) { Database.EnsureCreated(); } public DbSet<Product> Products { get; set; } } |
Клас контексту БД відповідно простий – хоча ситуація зміниться зі зростанням складності моделі даних у ваших проєктах.
Модель і Репозиторій
Модель для додатка Show буде заснована на списку товарів. Створіть папку Models і додайте в неї файл класу на ім’я Product.cs з таким вмістом:
1 2 3 4 5 6 7 |
public class Product { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal Price { get; set; } } |
Використання патерну “Сховище” (Repository), у якому інтерфейс визначає властивості та методи, призначені для доступу до даних, а для роботи з механізмом зберігання даних застосовується клас реалізації. Перевага використання патерну “Сховище” пов’язана з полегшенням модульного тестування частини MVC додатка, а також із тим, що деталі, які стосуються зберігання даних, приховані від інших частин додатка.
Щоб створити інтерфейс сховища, створіть папку Interfaces і додайте в неї файл інтерфейсу на ім’я IProduct.cs із таким вмістом:
1 2 3 4 |
public interface IProduct { Task<IEnumerable<Product>> GetProductsAsync(int page, int pageSize); } |
Створіть папку Repository і додайте в неї файл класу на ім’я ProductRepository.cs з таким вмістом:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class ProductRepository : IProduct { private readonly ApplicationContext _context; public ProductRepository(ApplicationContext context) { _context = context; } public async Task<IEnumerable<Product>> GetProductsAsync(int page, int pageSize) { return await _context.Products.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync(); } } |
У додатку ASP.NET Core MVC, доступ до об’єктів контексту даних управляється з використанням впровадження залежностей, і тому до класу ProductRepository було додано конструктор, який приймає об’єкт ApplicationContext, який буде надано засобом впровадження залежностей під час виконання.
Конфігурування постачальника бази даних і класу контексту
Додайте в клас Program.cs оператори конфігурації, щоб повідомити інфраструктуру Entity Framework Core про те, яким чином використовувати рядок підключення, який має застосовувати постачальник БД, і як керувати класом контексту:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Add services to the container. builder.Services.AddControllersWithViews(); //Новый код builder.Services.AddTransient<IProduct, ProductRepository>(); IConfigurationRoot _confString = new ConfigurationBuilder(). SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build(); builder.Services.AddDbContext<ApplicationContext>(options => options.UseSqlServer(_confString.GetConnectionString("DefaultConnection"))); //Новый код конец var app = builder.Build(); |
Метод AddDbContext<T>(), що розширює, застосовується для налаштування класу контексту, вказує інфраструктурі Entity Framework Core, який постачальник БД використовувати (у цьому разі за допомогою методу UseSqlServer(), але для кожного постачальника БД передбачено свій метод), і надає рядок під’єднання.
Початкові дані
Нерідко виникає необхідність, щоб база даних до моменту першого звернення додатка вже містила початкові дані, наприклад, базові ролі та обліковий запис адміністратора.
Для ініціалізації бази даних початковими ролями і користувачами, в папці Data, визначимо клас DbInit, з таким вмістом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class DbInit { private readonly ApplicationContext _context; public DbInit(ApplicationContext context) { _context = context; } public async Task InitializeAsync() { if (!await _context.Products.AnyAsync()) { List<Product> products = new List<Product>(); for (int i = 1; i <= 30; i++) { Product product = new Product { Name = "Product " + i, Description = "This is the description for Product " + i, Price = (decimal)(i * 10.99) // Example price calculation }; products.Add(product); } _context.Products.AddRange(products); await _context.SaveChangesAsync(); } } } |
Використовуємо цей клас, у класі Program після var app = builder.Build();:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; try { await new DbInit(services.GetRequiredService<ApplicationContext>()).InitializeAsync(); } catch (Exception ex) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occurred while seeding the database."); } } |
Тут за допомогою методу services.GetRequiredService() отримуємо сервіс ApplicationContext і передаємо їх у його метод InitializeAsync. У підсумку під час першого запуску в базу даних будуть додані всі необхідні дані.
Запустимо застосунок і перевіримо, щоб база даних успішно створилася, а таблиці з ролями і користувачами були заповнені:
Шановні ентузіасти програмування на C#!
З найкращими побажаннями,
[Леонід/ Dijix Company]
Контролер і подання
Перейдемо в контролер Home і визначимо в ньому такий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class HomeController : Controller { private readonly IProduct _products; public HomeController(IProduct products) { _products = products; } [Route("/")] [HttpGet] public async Task<IActionResult> Index(int page = 1, int pageSize = 10) { return View(await _products.GetProductsAsync(page, pageSize)); } [Route("get-more-products")] [HttpGet] public async Task<IActionResult> GetMoreProducts(int page = 1, int pageSize = 10) { return PartialView("_ProductsPartial",await _products.GetProductsAsync(page, pageSize)); } } |
Оскільки інформації про продукт не мало, винесемо його в окреме подання. Перейдемо в папку Views / Shared і додамо часткове подання _ProductPartial.cshtml, з таким вмістом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
@model Product <div class="row justify-content-center mb-3"> <div class="col-md-12 col-xl-10"> <div class="card shadow-0 border rounded-3"> <div class="card-body"> <div class="row"> <div class="col-md-12 col-lg-3 col-xl-3 mb-4 mb-lg-0"> <div class="bg-image hover-zoom ripple rounded ripple-surface"> <img src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/E-commerce/Products/img%20(4).webp" class="w-100" /> <a href="#!"> <div class="hover-overlay"> <div class="mask" style="background-color: rgba(253, 253, 253, 0.15);"></div> </div> </a> </div> </div> <div class="col-md-6 col-lg-6 col-xl-6"> <h5>@Model.Name</h5> <p class="mb-4 mb-md-0">@Model.Description</p> </div> <div class="col-md-6 col-lg-3 col-xl-3 border-sm-start-none border-start"> <div class="d-flex flex-row align-items-center mb-1"> <h4 class="mb-1 me-1">$@Model.Price</h4> </div> <h6 class="text-success">Free shipping</h6> <div class="d-flex flex-column mt-4"> <button class="btn btn-primary btn-sm" type="button">Details</button> <button class="btn btn-outline-primary btn-sm mt-2" type="button">Add to cart</button> </div> </div> </div> </div> </div> </div> </div> |
Перейдемо в подання Views / Home / Index.cshtml і визначимо в ньому такий вміст:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
@{ ViewData["Title"] = "All Products"; } @model IEnumerable<Product> <div class="container py-5" id="products"> @foreach (Product product in Model) { @await Html.PartialAsync("_ProductPartial", product) } </div> <div class="text-center"> <button id="showMore" class="btn btn-primary">Show more</button> </div> @section Scripts{ <script> var page = 2; //Начинаем со второй страницы, так как первая уже показана var pageSize = 10; $("#showMore").click(function () { $.ajax({ url: "/get-more-products?page=" + page + "&pageSize" + pageSize, success: function (data) { $("#products").append(data); page++; } }); }); </script> } |
Сторінка відображає початковий список продуктів. Під час натискання на кнопку “Show more”, спрацьовує JavaScript код, за допомогою якого надсилається запит за адресою “/get-more-products?page=” + page + “&pageSize”, у відповідь на цей запит ми отримуємо часткове представлення з даними про товари, яке успішно додаємо в основний блок на сторінку.
Перейдемо до папки Views / Shared і додамо часткове подання _ProductsPartial.cshtml, з таким вмістом:
1 2 3 4 5 6 |
@model IEnumerable<Product> @foreach (Product product in Model) { @await Html.PartialAsync("_ProductPartial", product) } |
За допомогою цього подання ми зможемо постачати певну кількість продуктів на основну сторінку. Запустимо проєкт і перевіримо його роботу.
Я сподіваюся, що вам сподобалося читати цю статтю, і вона виявилася легкою для розуміння. Будь ласка, дайте мені знати, якщо у вас є якісь коментарі або виправлення.
Так само вам може бути цікава попередня стаття – Створення додатка з використанням ASP.NET Core MVC і EF Core.
Ви хочете навчитися писати код мовою програмування C#?
Створювати різні інформаційні системи, що складаються з сайтів, мобільних клієнтів, десктопних додатків, телеграм-ботів тощо.
Переходьте до нас на сторінку Dijix і ознайомтеся з умовами навчання, ми спеціалізуємося тільки на індивідуальних заняттях, як для початківців, так і для просунутих програмістів. Ви можете взяти як одне заняття для опрацювання питання, що вас цікавить, так і кілька, для більш щільної роботи. Завдяки особистому кабінету, кожен студент підвищить якість свого навчання, у вашому розпорядженні:
- Доступ до пройденого матеріалу
- Тематичні статті
- Бібліотека книг
- Онлайн тестування
- Спілкування в закритих групах