在ASP.NET MVC 5中缓存列表

问题描述 投票:0回答:2

我的MVC APP中有成千上万的用户,我在用户表(by this tutorial)中使用排序,分页和搜索,但加载,排序或搜索需要很长时间。

所以我有用户列表

List<ApplicationUser> appUsers = _context.Users.ToList();

我有模型列表

List<RegisterViewModel> models = new List<RegisterViewModel>();
foreach (var au in appUsers)
{
    RegisterViewModel rvm = new RegisterViewModel(au);
    rvm.RoleName = UserManager.GetRoles(au.Id).First();
    models.Add(rvm); //new RegisterViewModel(au));
}

在模型中我搜索或排序。

缓存此模型列表的最简单方法是什么?如何使用缓存列表而不是创建新列表?

这是我完整的ActionResult Index()代码

[OutputCache(Duration = 120, VaryByParam = "*")]
[AuthLog(Roles = "SuperAdmin")]
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
    ViewBag.CurrentSort = sortOrder;
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
    ViewBag.EmailSortParm = sortOrder == "Email" ? "Email_desc" : "Email";

    if (searchString != null)
        page = 1;
    else
        searchString = currentFilter;

    ViewBag.CurrentFilter = searchString;

    List<ApplicationUser> appUsers = _context.Users.ToList();

    List<RegisterViewModel> models = new List<RegisterViewModel>();
    foreach (var au in appUsers)
    {
        RegisterViewModel rvm = new RegisterViewModel(au);
        rvm.RoleName = UserManager.GetRoles(au.Id).First();
        models.Add(rvm); //new RegisterViewModel(au));
    }

    if (!String.IsNullOrEmpty(searchString))
        models = models.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()) || s.Email.ToUpper().Contains(searchString.ToUpper())).ToList();

    switch (sortOrder)
    {
        case "Name_desc":
            models = models.OrderByDescending(x => x.Name).ToList();
            break;
        case "Email_desc":
            models = models.OrderByDescending(x => x.Email).ToList();
            break;
        case "Email":
            models = models.OrderBy(x => x.Email).ToList();
            break;
        default:
            models = models.OrderBy(x => x.Name).ToList();
            break;
    }
    int pageSize = 20;
    int pageNumber = (page ?? 1);

    ViewBag.Title = "Použivatelia";
    return View(models.AsEnumerable().ToPagedList(pageNumber, pageSize));
}
c# asp.net asp.net-mvc
2个回答
4
投票

我认为你需要在数据库而不是内存中进行排序和过滤。

不确定你的-_context是什么,但假设它是某种形式的ORM。问题是你在任何排序或过滤之前调用ToList,这意味着你的代码在内存中完成了一切。如果使用ORM功能,则可以通过简单地允许它生成更有效的SQL查询来避免缓存。


0
投票

您需要对数据库进行分页和排序,而不是撤回数千行,然后对该行进行分页或排序。

当你调用.ToList()时,它对你想要所有记录的数据库都是有意义的,然后它会拉回你表中的数千个,然后你才将你的排序和分页应用到已被带回内存的数据中。

而不是查询只根据页面大小和页码拉回10个已排序的记录,而是拉回4000然后进行排序/分页。

article about PagedList and sorting

© www.soinside.com 2019 - 2024. All rights reserved.