我处于一种奇怪的情况 - 我被要求优化依赖于延迟加载的搜索功能。我意识到速度的主要问题是由于分页请求(大约1.5秒)和代码之间的等待时间,我意识到控制器处理的每个页面请求都会导致模型执行完整的数据库查询(而不是仅针对该页面的结果的部分查询)。在.NET MVC控制器请求中坚持一个变量
我们使用的是自定义的ORM,所以我不确定它在分页方面如何处理(我认为这就是为什么以这种方式实现的原因)。我们将数据库结果存储到IEnumerable中,然后使用LINQ进行筛选以检索正确的页面结果。
我想要做的就是将这个请求缓存在内存中 - 因为我们把完整的结果放到一个IEnumerable中,将它放在某个地方会很方便(即使我必须将它传递到我的模型)。
有人建议在我的控制器或模型中使用静态变量,但我认为这会在多个请求中失败。我在想,可能会有一种方法将其暂时存储在服务器端的Session变量中,并在所有页面请求完成后将其删除。手动缓存,如果你愿意。
我知道这不是最好的方式来做到这一点,但它可能是我在优化方面唯一的理智选择(除非我们转向不同的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;
}
我最终使用这个答案缓存数据库请求,这太棒了!不幸的是,事实证明,这个问题的大部分都来自其他地方,而且要优化更难:....-( –