به منظور مشاهده نحوه بازیابی داده ها از SQL Server در صفحات NET Core Razor با استفاده از Entity Framework، می توانید از وبلاگ قبلی من دیدن کنید.
در زیر نرم افزار/مفاهیم مورد استفاده در این مقاله آورده شده است.
- ویژوال استودیو 2019
- Net Core 2.0
- صفحات تیغ
- زبان سی شارپ
پروژه خود را در Visual Studio 2019 باز کنید
در مورد من، من پروژه ایجاد شده قبلی را که در آن صفحات Razor وجود دارد باز می کنم.
صفحه Index (صفحه Razor) را که در آن داده ها وجود دارد باز کنید. در مثال خود، من Index.cshtml را در پوشه "Customers" باز می کنم، زیرا اطلاعات مشتری من در این صفحه نمایش داده می شود.
مرتب سازی را به صفحه Razor اضافه کنید
ما می توانیم یک ویژگی مرتب سازی را به تمام ستون های موجود در صفحه Index.cshtml (Razor Page) اضافه کنیم. در مثالم، من ستونهای زیر را دارم که باید مرتبسازی انجام شود.
شناسه مشتری (پنهان شده در صفحه داده)، نام خانوادگی، نام و ایمیل
برای مرتبسازی ستونها، ویژگیها را در صفحه Index.cshtml.cs اضافه کنید. در مثال من: من 4 ستون دارم، بنابراین 4 ویژگی ایجاد خواهم کرد.
- public class IndexModel : PageModel
- {
- private readonly ScaffModels.TestingCLRContext _context;
- public IndexModel(ScaffModels.TestingCLRContext context)
- {
- _context = context;
- }
- public string CustIDSort { get; set; }
- public string LNameSort { get; set; }
- public string FNameSort { get; set; }
- public string EmailSort { get; set; }
کاربر باید بتواند پس از کلیک بر روی عنوان ستون نمایش داده شده در صفحه، ستون را مرتب کند. برای رسیدن به این هدف، عنوان ستون را در داخل یک تگ لنگر قرار می دهیم. در مثال من: من 3 ستون را در داخل تگ anchor قرار داده ام، زیرا ستون (CustomerID) برای من مخفی است.
- @{
- ViewData["Title"] = "Index";
- }
- <h2>Index</h2>
- <p>
- <a asp-page="Create">Create New</a>
- </p>
- <table class="table">
- <thead>
- <tr>
- <th>
- <a asp-page="./Index" asp-route-sortOrder="@Model.FNameSort">@Html.DisplayNameFor(model => model.Customers[0].FirstName)</a>
- </th>
- <th>
- <a asp-page="./Index" asp-route-sortOrder="@Model.LNameSort">@Html.DisplayNameFor(model => model.Customers[0].LastName)</a>
- </th>
- <th>
- <a asp-page="./Index" asp-route-sortOrder="@Model.EmailSort">@Html.DisplayNameFor(model => model.Customers[0].Email)</a>
- </th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- @foreach (var item in Model.Customers)
از آنجایی که عنوان ستون قابل کلیک است و نام ستون را برای مرتب سازی به عنوان رشته Query در URL ارسال می کند، باید آن را ضبط کرده و بیشتر پردازش کنیم. برای رسیدن به این هدف، روش موجود "OnGetAsync" را در صفحه Index.cshtml.cs به روز کنید.
- public async Task OnGetAsync(string sortOrder)
- {
- CustIDSort = String.IsNullOrEmpty(sortOrder) ? "Cust_ID" : "";
- LNameSort = sortOrder == "LName_Asc_Sort" ? " LName_Desc_Sort" : " LName_Asc_Sort";
- FNameSort = sortOrder == "FName_Asc_Sort" ? " FName_Desc_Sort" : " FName_Asc_Sort";
- EmailSort = sortOrder == "Email_Asc_Sort" ? " Email_Desc_Sort" : " Email_Asc_Sort";
- IQueryable<ScaffModels.Customers> cust = from s in _context.Customers select s;
- switch (sortOrder)
- {
- case "Cust_ID":
- cust = cust.OrderByDescending(s => s.CustomerId);
- break;
- case " LName_Asc_Sort":
- cust = cust.OrderBy(s => s.LastName);
- break;
- case " LName_Desc_Sort":
- cust = cust. OrderByDescending (s => s.LastName);
- break;
- case " FName_Asc_Sort":
- cust = cust.OrderBy(s => s.FirstName);
- break;
- case " FName_Desc_Sort":
- cust = cust. OrderByDescending (s => s.FirstName);
- break;
- case " Email_Asc_Sort":
- cust = cust.OrderBy(s => s.Email);
- break;
- case " Email_Desc_Sort":
- cust = cust. OrderByDescending (s => s.Email);
- break;
- default:
- cust = cust.OrderBy(s => s.CustomerId);
- break;
- }
- Customers = await cust.AsNoTracking().ToListAsync();
- }
فایل ها را با کلیک راست روی فایل Index و باز کردن آن با مرورگر تست کنید. سپس روی عنوان ستون ها کلیک کنید
فیلترینگ (جعبه جستجو) را به صفحه Razor اضافه کنید
ما میتوانیم با قرار دادن کادر متنی برای کاربر برای جستجوی دادههای خود بر اساس هر موجودی در صفحه Index.cshtml (صفحه Razor) فیلتر را مجاز کنیم.
کاربر باید بتواند پس از وارد کردن عبارت جستجو در کادر جستجو و کلیک بر روی دکمه در صفحه، ستون را جستجو کند. برای رسیدن به این هدف، صفحه Index.cshtml را به روز می کنیم. در مثال من: من به کاربر اجازه میدهم فقط در LastName & FirstName جستجو کند.
- @{
- ViewData["Title"] = "Index";
- }
- <h2>Index</h2>
- <p>
- <a asp-page="Create">Create New</a>
- </p>
- <form asp-page="./Index" method="get">
- <div class="form-actions no-color">
- <p>
- Find by First or Last name: <input type="text" name="SearchString" value="@Model.CurrentFilter" />
- <input type="submit" value="Search" class="btn btn-default" /> ||
- <a asp-page="./Index">Back to full List</a>
- </p>
- </div>
- </form>
- <table class="table">
هنگامی که کاربر روی دکمه جستجو کلیک می کند، نام ستون به فیلتر به عنوان رشته Query در URL ارسال می شود. ما باید آن را بگیریم و بیشتر پردازش کنیم. برای رسیدن به این هدف، روش موجود "OnGetAsync" را در صفحه Index.cshtml.cs به روز کنید.
- public IndexModel(ScaffModels.TestingCLRContext context)
- {
- _context = context;
- }
- public string CustIDSort { get; set; }
- public string LNameSort { get; set; }
- public string FNameSort { get; set; }
- public string EmailSort { get; set; }
- public string CurrentFilter { get; set; }
- public async Task OnGetAsync(string sortOrder, string searchString)
- {
- CustIDSort = String.IsNullOrEmpty(sortOrder) ? "Cust_ID" : "";
- LNameSort = sortOrder == "LName_Asc_Sort" ? " LName_Desc_Sort" : " LName_Asc_Sort";
- FNameSort = sortOrder == "FName_Asc_Sort" ? " FName_Desc_Sort" : " FName_Asc_Sort";
- EmailSort = sortOrder == "Email_Asc_Sort" ? " Email_Desc_Sort" : " Email_Asc_Sort";
- CurrentFilter = searchString;
- IQueryable<ScaffModels.Customers> cust = from s in _context.Customers select s;
- if (!String.IsNullOrEmpty(searchString))
- cust = cust.Where(s => s.LastName.Contains(searchString) || s.FirstName.Contains(searchString));
- switch (sortOrder)
- {
فایل ها را با کلیک راست روی فایل Index و باز کردن آن با مرورگر تست کنید. سپس روی دکمه کلیک کنید تا LastName جستجو شود،
Paging را به صفحه Razor اضافه کنید
ما می توانیم یک ویژگی صفحه بندی را در صفحه Index.cshtml (Razor Page) اضافه کنیم تا عملکرد صفحه بهبود یابد و زمان بارگذاری صفحه کاهش یابد. ما از کلاس "PaginatedList" برای پشتیبانی از صفحه بندی استفاده می کنیم. این کلاس از دستورات «Skip» و «Take» برای فیلتر کردن دادههای روی سرور به جای بازیابی تمام ردیفهای جدول استفاده میکند.
کلاس PaginatedList.cs را در پروژه با کد زیر ایجاد کنید.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.EntityFrameworkCore;
- namespace Core.Test
- {
- public class PaginatedList<T> : List<T>
- {
- public int PageIndex { get; private set; }
- public int TotalPages { get; private set; }
- public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
- {
- PageIndex = pageIndex;
- TotalPages = (int)Math.Ceiling(count / (double)pageSize);
- this.AddRange(items);
- }
- public bool HasPreviousPage
- {
- get { return (PageIndex > 1); }
- }
- public bool HasNextPage
- {
- get { return (PageIndex < TotalPages); }
- }
- public static async Task<PaginatedList<T>> CreateAsync(
- IQueryable<T> source, int pageIndex, int pageSize)
- {
- var count = await source.CountAsync();
- var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
- return new PaginatedList<T>(items, count, pageIndex, pageSize);
- }
- }
- }
اکنون باید بفهمیم که آیا فیلتری قبلاً روی صفحه اعمال شده است، زمانی که صفحه بعدی یا قبلی کلیک شده است. همچنین باید بدانیم که آیا کاربر قبلاً از صفحه قبلی آمده است یا خیر. برای رسیدن به این هدف، روش موجود "OnGetAsync" را در صفحه Index.cshtml.cs به روز کنید.