简体   繁体   English

ASP.NET Core MVC中的过滤和排序

[英]Filtering and Sorting in ASP.NET Core MVC

I am new to ASP.NET Core MVC, and I want to see if it ok to implement sorting and to filter this way.我是 ASP.NET Core MVC 的新手,我想看看是否可以通过这种方式实现排序和过滤。 I have seen Microsoft tutorials about it, but I could not implement it like them.我看过微软关于它的教程,但我无法像他们那样实现它。 The context will be changed later with View Model.稍后将使用 View Model 更改上下文。

Index view:索引视图:

@model ProductListVM
@{
}


<h2>All Products</h2>

<hr />

<form class="row form-inline" onsubmit="onSubmit()" asp-action="Index" method="get" id="productsForm">
    <div class="col-sm-2">
        <select class="form-select" asp-for="CategoryId" onchange="filterAndSortProducts()" asp-items="ViewBag.Categories" style="width: 100%;">
            <option>Select Category</option>
        </select>
    </div>
    <div class="col-sm-2">
        <select asp-for="SortParam" onchange="filterAndSortProducts()" class="form-select" style="width: 100%;" asp-items="ViewBag.SortItems">
            <option value="">Sort By</option>
        </select>
    </div>
    <div class="col-sm-3">
        <div class="input-group">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="SearchString" value="@ViewData["CurrentFilter"]" />
            <button class="btn btn-outline-primary my-2 my-sm-0" type="submit" onsubmit="onsubmit()">Search</button>
        </div>
    </div>
</form>

<hr />

<div class="row">
    @foreach(var item in Model.Products) {
        <div class="col-md-3 col-sm-6">
            <div class="product-grid">
                <div class="product-image">
                    <a href="#" class="image">
                        <img class="pic-1" src="~/images/@item.ImagePath">
                    </a>
                    @if(item.IsOnSale) {
                        <span class="product-sale-label">Sale!</span>
                    }
                    <ul class="product-links">
                        <li><a href="#"><i class="fa fa-shopping-bag"></i> Add to cart</a></li>
                        <li><a href="#"><i class="fa fa-search"></i>Quick View</a>

        </li>
                    </ul>
                </div>
                <div class="product-content">
                    <h3 class="title"><a href="#">@item.Name</a></h3>
                    <div class="price">@if (item.IsOnSale)
                        {
                            <span>$@item.Price</span>
                        } $@item.CurrentPrice</div>
                </div>
            </div>
        </div>
    }
</div>

<script>
    function filterAndSortProducts(e) {
        var form = document.getElementById("productsForm");
        form.submit();
    }

    function onSubmit(e) {
        e.preventDefault();
    }

</script> 

View Model:查看 Model:

namespace ECommerce.Common.Models
{
    public class ProductListVM
    {
        public string? SortParam { get; set; }
        public int CategoryId { get; set; }
        public List<ProductVM>? Products { get; set; }
    }
}

Controller, Index action: Controller,索引动作:

        public async Task<IActionResult> Index(string searchString, ProductListVM model)
        {

            var sortParam = model.SortParam;
            var categoryFilterId = model.CategoryId;
            ViewData["CurrentFilter"] = searchString;
            var products = new List<Product>();

            if (!string.IsNullOrEmpty(searchString))
            {
                products = await productRepository.GetAllWithSearchStringAsync(searchString);
            }
            else
            {
                products = await productRepository.GetAllAsync();
            };

            switch (sortParam)
            {
                case "price_desc":
                    products = products.OrderByDescending(s => s.Price).ToList();
                    break;
                case "price_asc":
                    products = products.OrderBy(s => s.Price).ToList();
                    break;
                case "date_desc":
                    products = products.OrderByDescending(s => s.DateCreated).ToList();
                    break;
                case "date_asc":
                    products = products.OrderBy(s => s.DateCreated).ToList();
                    break;
                default:
                    products = products.OrderBy(s => s.DateCreated).ToList();
                    break;
            }

            if(categoryFilterId != 0) 
                products = products.Where(q => q.ProductCategoryId == categoryFilterId).ToList();
            

            ViewBag.SortItems = new List<SelectListItem>()
            {
                new SelectListItem() { Text = "Price: Highest to Lowest", Value = "price_desc"},
                new SelectListItem() { Text = "Price: Lowest to Highest", Value = "price_asc"},
                new SelectListItem() { Text = "Date: Newest to Oldest", Value = "date_desc"},
                new SelectListItem() { Text = "Date: Oldest to Newest", Value = "date_asc"},
            };
            ViewBag.Categories = new SelectList(context.Categories, "Id", "Name");
            model = new ProductListVM
            {
                Products = mapper.Map<List<ProductVM>>(products)
            };
            return View(model);
        }

Dates also will be changed, it is just an example at the moment.日期也将更改,目前只是一个示例。 Any suggestion, critique, or tip is helpful.任何建议、批评或提示都是有帮助的。 I am in learning progress.我在学习进步。

I think your using EF and the productRepository is a DBContext.我认为您使用 EF 和 productRepository 是一个 DBContext。 This gives you back a IEnumerable which is only evaluatet if you use the Data.这会给你一个 IEnumerable,它只有在你使用数据时才会被评估。 My Tipp for you to call.ToList() just in the End.我的 Tipp 让你在最后调用.ToList()。 It makes a big difference in performance.它在性能上有很大的不同。

    List<Product> products = productRepository.Products;

      if (!string.IsNullOrEmpty(searchString))
      {
        products = await products.WhereAsync(p = p.Where(s => s.Name.Contains(searchString)));
      }

      if (categoryFilterId != 0)
      {
        products = products.Where(q => q.ProductCategoryId == categoryFilterId);
      }

      switch (model.SortParam)
      {
        case SortOrder.price_desc:
          products = products.OrderByDescending(s => s.Price);
          break;
        case SortOrder.price_asc:
          products = products.OrderBy(s => s.Price);
          break;
        case SortOrder.date_desc:
          products = products.OrderByDescending(s => s.DateCreated);
          break;
        default:
          products = products.OrderBy(s => s.DateCreated);
          break;
      }

I would also use a Enum for you SortParam.我也会为你使用一个枚举 SortParam。

public enum SortOrder
{
  price_desc,
  price_asc,
  date_desc,
  date_asc
}

Hope that helps希望有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM