简体   繁体   English

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

[英]How to get a count of records with entity framework and repository pattern

We have developed an application in MVC, using entity framework and the repository pattern.我们在 MVC 中开发了一个应用程序,使用实体框架和存储库模式。 When a user logs in they see a dashboard with several counts of shifts depending on their status.当用户登录时,他们会看到一个仪表板,根据他们的状态,有多个轮班计数。 See below:见下文:

在此处输入图片说明

In the controller we populate the ViewModel using the following line:在控制器中,我们使用以下行填充 ViewModel:

viewModel.shiftsInProgress = _shiftDateService.GetShiftDatesByStatusID(72).Count();

This links to the following method:这链接到以下方法:

 public IList<ShiftDate> GetShiftDatesByStatusID(int statusID)
    {
        return _UoW.ShiftDates.Get(s => s.shiftDateStatusID == statusID)
            .OrderByDescending(s => s.shiftID).ToList();
    }

This method is also used to pull out the list of shifts by status in another view.此方法还用于在另一个视图中按状态拉出班次列表。

Our Unit of Work (_UOW) is mapped to a generic repository which contains 2 get methods:我们的工作单元 (_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();
    }

I am looking some advice on whether or not this is best practice, the queries on the dashboard where the counts are being pulled out are starting to slow the application down.我正在寻找一些关于这是否是最佳实践的建议,仪表板上的查询正在拉出计数开始减慢应用程序。 I'm thinking this is because we are pulling back an ilist for each count on the dashboard and then using the Count() method inside the controller for each.我认为这是因为我们正在为仪表板上的每个计数拉回一个 ilist,然后在控制器中为每个计数使用 Count() 方法。

Should I do the following?我应该做以下事情吗?

  1. Add another method to the generic repository, IEnumerable GetAll();将另一个方法添加到通用存储库中,IEnumerable GetAll(); - then use this to get a count of the records. - 然后使用它来获取记录数。

  2. Use the method 'GetWithRawSql' and then use SQL to get a count.使用方法“GetWithRawSql”,然后使用 SQL 获取计数。

  3. Something else?还有什么? Like below:像下面这样:

Would I be better removing the 'Shifts Completed' count then bring back an IList of all incomplete shifts to the controller.我会更好地删除“已完成班次”计数,然后将所有未完成班次的 IList 带回控制器。 Inside the controller then use linq to query by status and use the count() method.在控制器内部,然后使用 linq 按状态查询并使用 count() 方法。 ie IE

ilist<shiftdate> allIncompleteShifts = _shiftService.GetIncompleteShifts.ToList();

ViewModel.InProgress = allIncompleteShifts.Where(s => s.status ==72).Count();
ViewModel.Submitted = allIncompleteShifts.Where(s => s.status ==73).Count();

How would this affect performance这将如何影响性能

You have several options here.您在这里有多种选择。 One commonly used approach is, to return an IQueryable<TEntity> from your repository instead of returning an IList<TEntity> .一种常用的方法是从存储库返回IQueryable<TEntity>而不是返回IList<TEntity>

With this approach, the queries are executed on the database and not in-memory.使用这种方法,查询是在数据库上而不是在内存中执行的。 This includes filtering, ordering, etc. Also the Count() will be translated to the according SQL and executed on the database.这包括过滤、排序等。此外, Count()将被转换为相应的 SQL 并在数据库上执行。

Another approach would be to create a less-generic repository which also includes specific queries.另一种方法是创建一个不太通用的存储库,其中还包括特定的查询。

There is a discussion whether you should expose an IQueryable<TEntity> in this question . 在这个问题中讨论了是否应该公开IQueryable<TEntity> The conclusio is: It depends, whether you want to give the users of the repository more flexibility with IQueryable<TEntity> .结论是:这取决于您是否希望使用IQueryable<TEntity>为存储库的用户提供更大的灵活性。 You must then keep in mind that users can now perform queries which you might have not intended.然后您必须记住,用户现在可以执行您可能不打算执行的查询。 You can find more details on this in the given link.您可以在给定的链接中找到更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM