我们使用实体框架和存储库模式在MVC中开发了一个应用程序。当用户登录时,他们会看到一个仪表板,其中包含多个轮班计数,具体取决于其状态。见下文:
在控制器中,我们使用以下行填充ViewModel:
viewModel.shiftsInProgress = _shiftDateService.GetShiftDatesByStatusID(72).Count();
这链接到以下方法:
public IList<ShiftDate> GetShiftDatesByStatusID(int statusID)
{
return _UoW.ShiftDates.Get(s => s.shiftDateStatusID == statusID)
.OrderByDescending(s => s.shiftID).ToList();
}
此方法还用于在另一个视图中按状态提取班次列表。
我们的工作单元(_UOW)映射到包含2个get方法的通用存储库:
public IList<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
我正在寻找一些关于这是否是最佳做法的建议,仪表板上计数被抽出的查询开始减慢应用程序的速度。我想这是因为我们在仪表板上为每个计数拉回一个ilist,然后在控制器内部使用Count()方法。
我应该这样做吗?
向通用存储库添加另一个方法,IEnumerable GetAll(); - 然后用它来计算记录。
使用方法'GetWithRawSql'然后使用SQL来计算。
还有别的吗?如下所示:
我是否会更好地删除“班次已完成”计数,然后将所有未完成班次的IList带回控制器。在控制器内部,然后使用linq按状态查询并使用count()方法。即。
ilist<shiftdate> allIncompleteShifts = _shiftService.GetIncompleteShifts.ToList();
ViewModel.InProgress = allIncompleteShifts.Where(s => s.status ==72).Count();
ViewModel.Submitted = allIncompleteShifts.Where(s => s.status ==73).Count();
这将如何影响效果
答案 0 :(得分:2)
这里有几个选项。一种常用方法是从存储库返回IQueryable<TEntity>
而不是返回IList<TEntity>
。
使用此方法,查询将在数据库上执行,而不是在内存中执行。这包括过滤,排序等。Count()
也将被转换为相应的SQL并在数据库上执行。
另一种方法是创建一个不太通用的存储库,其中还包含特定的查询。
讨论是否应公开IQueryable<TEntity>
in this question。 conclusio是:取决于您是否希望使用IQueryable<TEntity>
为存储库的用户提供更大的灵活性。然后,您必须记住,用户现在可以执行您可能没有打算的查询。您可以在给定的链接中找到有关此内容的更多详细信息。