如何使用实体框架和存储库模式获取记录计数

时间:2017-01-31 10:42:44

标签: c# asp.net-mvc entity-framework linq

我们使用实体框架和存储库模式在MVC中开发了一个应用程序。当用户登录时,他们会看到一个仪表板,其中包含多个轮班计数,具体取决于其状态。见下文:

enter image description here

在控制器中,我们使用以下行填充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()方法。

我应该这样做吗?

  1. 向通用存储库添加另一个方法,IEnumerable GetAll(); - 然后用它来计算记录。

  2. 使用方法'GetWithRawSql'然后使用SQL来计算。

  3. 还有别的吗?如下所示:

  4. 我是否会更好地删除“班次已完成”计数,然后将所有未完成班次的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();
    

    这将如何影响效果

1 个答案:

答案 0 :(得分:2)

这里有几个选项。一种常用方法是从存储库返回IQueryable<TEntity>而不是返回IList<TEntity>

使用此方法,查询将在数据库上执行,而不是在内存中执行。这包括过滤,排序等。Count()也将被转换为相应的SQL并在数据库上执行。

另一种方法是创建一个不太通用的存储库,其中还包含特定的查询。

讨论是否应公开IQueryable<TEntity> in this question。 conclusio是:取决于您是否希望使用IQueryable<TEntity>为存储库的用户提供更大的灵活性。然后,您必须记住,用户现在可以执行您可能没有打算的查询。您可以在给定的链接中找到有关此内容的更多详细信息。