مرتب‌ سازی لیست در ASP.NET Core – جلسه ۵۵

Sort List ASPNET Core MVC - Session55

در این جلسه به مرتب‌ سازی لیست در ASP.NET Core خواهیم پرداخت و روش پیاده‌سازی آن بروی پروژه با معماری MVC را شرح خواهیم داد. همانگونه که میدانید، عملیات مرتب سازی به دو صورت صعودی (Ascending) و یا نزولی (Descending) صورت می‌گیرد. ما در این جلسه تغییراتی برروی پروژه مربوطه اعمال میکنیم تا قادر به اعمال هر دو روش جستجو باشیم. همچنین در این جلسه، از ساختار شرطی Switch Case استفاده خواهیم کرد.

مرتب سازی لیست در ASP.NET Core

برای مرتب سازی لیست، ابتدا کاربر باید درخواست مرتب سازی را به کنترلر و در نهایت به ریپازیتوری ارسال نماید. روشهای مختلفی برای این منظور وجود دارد. ما در این دوره با ارسال درخواست از طریق Query String اقدام میکنیم. برای درک بهتر این موضوع ما به از پروژه وب اپلیکیشن مربوط به این دوره استفاده میکنیم و عملیات مرتب سازی را برروی لیست هزینه‌ها (Cost List) اعمال می‌کنیم.

ابتدا در لیست نامبرده تغییراتی بروی تیترهای Cost و Payment Method اعمال میکنیم تا بتوانیم درخواست مرتب سازی را به کنترلر ارسال نماییم.

            <th>ID</th>
            @{
                var sortBy = Context.Request.Query["sortby"] == "amount" ? "amountdesc" : "amount";
            }
            <th><a asp-action="index" asp-route-sortby="@sortBy" 
                asp-route-page="@Context.Request.Query["page"]"
                asp-route-searchby="@Context.Request.Query["searchby"]"
                asp-route-searchfor="@Context.Request.Query["searchfor"]">Amount</a></th>
            <th>Category</th>
            <th>Comment</th>
            @{
                sortBy = Context.Request.Query["sortby"] == "paymentmethod" ? "paymentmethoddesc" : "paymentmethod";
            }
            <th><a asp-action="index" asp-route-sortby="@sortBy"
                asp-route-page="@Context.Request.Query["page"]"
                asp-route-searchby="@Context.Request.Query["searchby"]"
                asp-route-searchfor="@Context.Request.Query["searchfor"]">Payment Method</a></th>
            <th colspan="3" class="text-center">Actions</th>
        </tr>

همانگونه که در کد فوق مشاهده می‌کنید، تیترهای ذکر شده به صورت لینک در آمده و با استفاده از تگ هلپر asp-route اقدام به ارسال مقادیر مورد نیاز به کنترلر میکنیم. قطعه کد کلی مربوط به نمای Cost/Index در زیر قابل مشاهده میباشد.

@model IEnumerable<CostList>
@using X.PagedList;
@using X.PagedList.Mvc.Core;
@{
    ViewBag.Title = "Cost List";
}
<div class="row">
    <div class=col-3>
        <a asp-controller="cost" asp-action="create" class="btn btn-primary mx-2 my-2">Create New Cost</a>
    </div>
    <div class="col-6 offset-3">
        <form asp-controller="Cost" asp-action="Index" method="get" class="my-2 mx-2">
            <div class="input-group">
                <select class="form-select" id="inputSearch" name="searchby">
                    <option selected value="">Search by...</option>
                    <option value="comment">Comment</option>
                    <option value="category">Category</option>
                </select>
                <input name="searchfor" class="form-control" id="inputSearch" aria-describedby="inputSearchComment" aria-label="Search">
                <button class="btn btn-outline-secondary" type="submit" id="inputSearch">Search</button>
                <a class="btn btn-outline-primary" type="button" asp-controller="cost" asp-action="index">Clear Search</a>
            </div>
        </form>
    </div>
</div>
<table class="table table-dark">
    <thead>
        <tr>
            <th>ID</th>
            @{
                var sortBy = Context.Request.Query["sortby"] == "amount" ? "amountdesc" : "amount";
            }
            <th><a asp-action="index" asp-route-sortby="@sortBy" 
                asp-route-page="@Context.Request.Query["page"]"
                asp-route-searchby="@Context.Request.Query["searchby"]"
                asp-route-searchfor="@Context.Request.Query["searchfor"]">Amount</a></th>
            <th>Category</th>
            <th>Comment</th>
            @{
                sortBy = Context.Request.Query["sortby"] == "paymentmethod" ? "paymentmethoddesc" : "paymentmethod";
            }
            <th><a asp-action="index" asp-route-sortby="@sortBy"
                asp-route-page="@Context.Request.Query["page"]"
                asp-route-searchby="@Context.Request.Query["searchby"]"
                asp-route-searchfor="@Context.Request.Query["searchfor"]">Payment Method</a></th>
            <th colspan="3" class="text-center">Actions</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var cost in Model)
        {
            <tr>
                <td>@cost.ID</td>
                <td>@cost.Amount</td>
                <td>@cost.CategoryName</td>
                <td>@cost.Comment</td>
                <td>@cost.PaymentMethod</td>
                <form asp-controller="cost" asp-action="delete" asp-route-id="@cost.ID" method="post">
                <td><a class="btn btn-primary d-block" asp-controller="cost" asp-action="detail" asp-route-id="@cost.ID">View</a></td>
                <td><a class="btn btn-info btn-block d-block" asp-controller="cost" asp-action="update" asp-route-id="@cost.ID">Edit</a></td>
                <td><button class="btn btn-danger btn-block d-block" type="submit">Delete</button></td>
                </form>
            </tr>
        }
    </tbody>
</table>
@Html.PagedListPager((IPagedList) Model, page => Url.Action("Index", new {page = page,
searchfor = @Context.Request.Query["searchfor"],
searchby = @Context.Request.Query["searchby"],
sortby = @Context.Request.Query["sortby"]}),
new X.PagedList.Web.Common.PagedListRenderOptions {
    LiElementClasses = new string[] {"page-item"},
    PageClasses = new string[] { "page-link" }
})

حال میبایست درخواست مورد نظر را جهت مرتب سازی بروی لیست اعمال نماییم. برای این کار، ابتدا در متد GetCostList درون اینترفیس و سپس درون ریپازیتوری تغییرات مورد نظر را اعمال میکنیم.

    public interface ICostRepository
    {
        Cost GetCostByID(int id);
        IEnumerable<Cost> GetAllCost();
        Cost Create(Cost NewCost);
        Cost Update(Cost UpdateCost);
        Cost Delete(int id);
        List<CostList> GetCostList(string searchby, string searchfor, string sortby);
    }
}

همانگونه که در کد فوق مشاهده می‌کنید، sortby به صورت رشته‌ایی به عنوان مقدار ورودی متد GetCostList اضافه گردیده، حال نیاز به اعمال تغییرات لازم بر‌روی ریپازیتوری می‌باشد.

        public List<CostList> GetCostList(string searchby, string searchfor, string sortby)
        {
            var CL = context.Costs.Join(context.Categories, costen => costen.CategoryID, caten => caten.ID, (costen, caten) => new { costen, caten }).
                Select(sel => new 
                {
                    sel.costen.ID,
                    sel.costen.Amount,
                    sel.costen.Comment,
                    sel.costen.PaymentMethod,
                    sel.caten.CategoryName
                }).ToList();
            if(searchby == "comment" && searchfor != null)
            {
                CL = CL.Where(ser => ser.Comment!=null ? ser.Comment.ToLower().Contains(searchfor.ToLower()) : ser.Comment != null).ToList();
            }
            if (searchby == "category" && searchfor != null)
            {
                CL = CL.Where(ser => ser.CategoryName.ToLower() == searchfor.ToLower()).ToList();
            }
            List<CostList> costList = new();
            foreach (var cost in CL)
            {
                costList.Add(new CostList
                {
                    ID = cost.ID,
                    Amount = cost.Amount,
                    Comment = cost.Comment,
                    PaymentMethod = cost.PaymentMethod,
                    CategoryName = cost.CategoryName
                });
            }
            switch (sortby)
            {
                case "amount":
                    costList = costList.OrderBy(o => o.Amount).ToList();
                    break;
                case "amountdesc":
                    costList = costList.OrderByDescending(o => o.Amount).ToList();
                    break;
                case "paymentmethod":
                    costList = costList.OrderBy(o => o.PaymentMethod).ToList();
                    break;
                case "paymentmethoddesc":
                    costList = costList.OrderByDescending(o => o.PaymentMethod).ToList();
                    break;
                default:
                    break;
            }
            return costList;
        }

همانگونه که مشاهده میکنید، در انتهای متد مورد نظر و قبل از ارسال لیست با استفاده از Switch Case مقدار مرتب سازی ارسالی بررسی میگردد و لیست بر اساس آن مرتب میگردد. همچنین نیاز است تغییراتی در کنترلر و اکشن متد مربوطه اعمال کنیم.

        [HttpGet]
        public IActionResult Index(string searchby, string searchfor, int? page, string sortby)
        {
            var costs = costRepository.GetCostList(searchby, searchfor,sortby).ToPagedList(page ?? 1, 5);
            return View(costs);
        }

با اضافه نمودن مقدار ورودی sortby به Cost/Index و ارسال آن به رپازیتوری، لیست مرتب شده را میتوانیم به نما جهت رندر ارسال نماییم.

در صورت نیاز به جزئیات بیشتر، میتوانید ویدئو آموزشی این جلسه را تماشا نمایید. همچنین برای آگاهی از جلسات بعدی این دوره آموزشی، ما را در اینستاگرام، تلگرام، یوتیوب و آپارات دنبال کنید. ضمنا لیست کامل جلسات در این قسمت در دسترس شما میباشد و سورس کد این جلسه را میتوانید از GitHub ما دانلود نمایید.

تماشای ویدیو در یوتیوب ما

دانلود اسلایدهای آموزشی این جلسه از اینجا

برچسب ها

0 0 رای ها
امتیازدهی به مقاله
اشتراک در
اطلاع از
guest
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
0
افکار شما را دوست داریم، لطفا نظر دهید.x