2016-03-16 2 views
0

У меня есть тысячи пользователей в моем MVC APP, и я использую сортировку, поиск подкачки и поиск в моей таблице пользователей (by this tutorial), но для загрузки, сортировки или поиск.Кэширование списка в ASP.NET MVC 5

Так что у меня список пользователей

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)); 
} 
+0

Вы пробовали [MemoryCache] (https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache (v = vs.110) .aspx) класс ? –

+1

Я бы сначала исследовал, почему для поиска и сортировки требуется много времени. Предполагая, что вы используете базу данных в качестве хранилища, вы можете исправить это с помощью индекса или 2, индексированного представления или чего-то еще. Если общий список пользователей невероятно длинный или часто изменяется, то в хранилище памяти, вероятно, не лучший способ. Даже с миллионами записей в таблице данных мелкозернистый запрос и соответствующие индексы должны возвращать результаты относительно быстро. Кроме того, возможно, это даже не база данных, которая медленная, но что-то еще вы загружаете. Вы не сможете сказать без какого-либо профилирования. – Igor

ответ

4

Я думаю, что вы должны сделать свою сортировку и фильтрацию в базе данных, а не памяти.

Не знаете, что такое -_context, но предположим, что это ORM. Проблема заключается в том, что вы вызываете ToList перед любой сортировкой или фильтрацией, что означает, что все сделано в памяти вашим кодом. Если вы используете возможности ORM, вы, вероятно, можете избежать необходимости кэширования, просто позвольте ему генерировать более эффективные SQL-запросы.

+1

Согласен. Обратите внимание, что [учебник, на который ссылается ОП] (http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with -the-entity-framework-in-as-asp-net-mvc-application) не вызывает 'ToList' inline, как в коде OP. Сохранение всей таблицы в памяти, вероятно, не будет быстрее, чем фильтрация данных * до того, как она будет извлечена. – NightOwl888

+0

У меня нет проблем только с сортировкой или поиском в моем списке, но также с моей начальной загрузкой. Начальная загрузка занимает около 70 секунд -> это действительно плохо. – Kicker

+0

Тем более, что вы должны фильтровать данные, которые вы загружаете сначала, а не загружать все за один раз –

0

Вы должны делать пейджинг и сортировку по базе данных, а не вытягивать тысячи строк, а затем выполнять разбивку по страницам или сортировку по этим строкам.

Когда вы вызываете .ToList(), это означает, что в базу данных вы хотите, чтобы все записи были возвращены, а затем она возвращает тысячи в вашем столе, и только после этого вы применяете свою сортировку и подкачку к тем, которые были возвращены в память.

Вместо запроса только отбрасывание 10 отсортированных записей на основе размера страницы и номера страницы, который вы отбрасываете, говорят 4000, а затем выполняют сортировку/подкачку.

См article about PagedList and sorting