Я в необычной ситуации - меня попросили оптимизировать функцию поиска, которая зависит от ленивой загрузки. Я понял, что основная проблема со скоростью связана с временем ожидания между запросами подкачки (примерно 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;
}
В итоге я использовал этот ответ для кэширования запроса db, что было здорово! К сожалению, как выясняется, основная часть проблемы находится в другом месте и гораздо сложнее оптимизировать .... :-( –