2014-02-09 2 views
0

Я в необычной ситуации - меня попросили оптимизировать функцию поиска, которая зависит от ленивой загрузки. Я понял, что основная проблема со скоростью связана с временем ожидания между запросами подкачки (примерно 1,5 секунды) и кодом, я понимаю, что каждый запрос страницы, который обрабатывает контроллер, заставляет модель выполнять полный запрос БД (вместо частичный запрос только для результатов этой страницы).Сохранение переменной в запросах контроллера .NET MVC

Мы используем пользовательский ORM, поэтому я не уверен, что он обрабатывает с точки зрения поискового вызова (и я думаю, именно поэтому он был реализован таким образом). Мы сохраняем результаты DB для IEnumerable, которые затем фильтруем с помощью LINQ для получения правильных результатов страницы.

То, что я хотел бы сделать, это кэшировать этот запрос в памяти - поскольку мы помещаем полный результат в IEnumerable, было бы удобно просто держать это где-то (даже если мне нужно передать его в моя модель).

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

Я знаю, что это не лучший способ сделать это, но это может быть единственный разумный вариант, который я имею в плане оптимизации (если мы не перейдем к другому ORM). Есть ли у кого-нибудь предложения, идеи или критические замечания? Как мне реализовать что-то подобное?

спасибо.

контроллер код: метод

[HttpGet, JsonErrorCatcher, NoCache] 
    public ActionResult Accounts(int page = 0) 
    { 
     using (var context = PersistenceContext.Create()) 
     { 
      var model = new ContactsModel(context); 
      return new JsonNetResult(model.GetAccountsWebView(CurrentUser, page)); 
     } 
    } 

Модель:

public ContactsWebViewModel GetAccountsWebView(User user, int page) 
    { 
     // This is what I'd like to avoid doing every time, by persisting this value. 
     // I can pass it into this method if necessary. 
     IEnumerable<Account> accounts = Context.Get<Account>() 
      .Include(x => x.AssignedGroups) 
      .Include(x => x.AssignedUsers) 
      .Include(x => x.Contacts) 
      .Where(x => x.IsActive) 
      .OrderBy(x => x.Name) 
      .ToArray(); 
     if (!user.HasPermission("Administrator.Contacts:View")) accounts = accounts.Where(x => x.IsReadableBy(user)); 
     int totalPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(accounts.Count())/25.0)); 
     accounts = accounts.Skip(page * 25).Take(25); 
     var model = GetWebView(user, null, accounts, page == 0); 
     model.TotalPages = totalPages; 
     return model; 
    } 

ответ

1

Если данные вы хотите кэш только для чтения и тот же для всех пользователей, то с помощью static переменной не является вопрос.

Если это не так, вы должны кэшировать IEnumerable как CacheItem в объекте System.Runtime.Caching.MemoryCache. Вы можете кэшировать несколько версий, чтобы соответствовать различным сценариям, которые могут потребоваться.

Подробнее о MemoryCache on MSDN.

+0

В итоге я использовал этот ответ для кэширования запроса db, что было здорово! К сожалению, как выясняется, основная часть проблемы находится в другом месте и гораздо сложнее оптимизировать .... :-( –

2

Простейшим решением, вероятно, является использование встроенного кэша asp.net. Вы не говорите, какую версию фреймворка используете, но что-то вроде этого должно работать.

if (HttpContext.Cache["Key1"] == null) 
    HttpContext.Cache.Add("Key1", "Value 1", null, DateTime.Now.AddSeconds(60), 
     Cache.NoSlidingExpiration, CacheItemPriority.High, null); 

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

Критерии поиска могут быть ключевыми, если те же результаты всегда возвращаются с одинаковыми критериями поиска.

 Смежные вопросы

  • Нет связанных вопросов^_^