我们使用实体框架和存储库模式在MVC中开发了一个应用程序。当用户登录时,他们会根据他们的状态看到具有多次班次计数的仪表板。见下文:如何使用实体框架和存储库模式获得记录数
在控制器我们填充使用视图模型下面的行:
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();
这将如何影响性能
您必须了解EF Query Deferred,通用资源库返回'列表()',首先您选择'select',然后您在内存中计算这些选定的项目。更好的性能将只使用'Count'像:'context.SomeEntity.Count(d => d.status == 73);' –
是的,将结果放入列表会减慢执行速度,因为它必须拉回所有的结果。最好的办法是操纵你的IQueryable对象,直到你有一个可以在数据库上执行的查询。你应该使用'allIncompleteShifts.Where(s => s.status == 72).Count();'但我无法真正告诉你什么是正确的应用程序在哪里应该公开这个功能。 – Luke
知识库中的关键点是什么?在没有Get方法的情况下,您可以按照完全相同的方式(甚至更好)执行Where,Include,OrderBy。 – Evk