使用ToList()和使用IList从存储库返回IEnumerable

Cod*_*ody 6 c# asp.net-mvc performance repository-pattern

更新3/31/2017

自从这篇文章以来我已经学到了更多的东西,所以想要ToList从存储库返回时给出一个重要的理由- 调用ToList将(当使用IQueryable时)在数据库上执行已翻译的SQL而不是将记录拉入内存然后过滤.我不相信IEnumerable或IList的隐式转换会这样做.


在MSDN网站上的一些教程之后,我在我的应用程序中使用了通用存储库层.此存储库层由我的服务层调用,而服务层又由控制器调用.

查看通用存储库,获取数据并通过调用返回ToList().但是,方法的返回类型IEnumerable意味着服务层必须接受,IEnumerable并且在返回控制器之前必须再次调用ToList()on IEnumerable.

示例 - 存储库:

public IEnumerable<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);
    }

    return orderBy != null ? orderBy(query).ToList() : query.ToList();
}
Run Code Online (Sandbox Code Playgroud)

示例 - 服务层

public IList<DOC> SearchDocuments(string docInfo)
{
    // build the predicate and logic, etc

    // grab all the matching documents with the relationships
    IEnumerable<DOC> documents = _unitOfWork.DocumentRepository.Get(
        predicate,
        p => p.OrderBy(d => d.DocInfo),
        "DocRelationship, DocRelationship.OtherDocTable");

    return documents.ToList();
} 
Run Code Online (Sandbox Code Playgroud)

从我已经完成的阅读中,似乎最好简单地向控制器呈现List它需要的对象IEnumerable或对象IQueryable.

因此,我认为最好不要返回一个IEnumerable返回IList来代替.我在这里遗漏了什么 - 为什么MSDN团队会选择IEnumerable设计并致电ToList?这会有用吗?在我看来,不止一次进行转换似乎是低效且毫无意义的,特别是在处理大量数据时.

如果不清楚或已经有答案,我提前道歉,但我一直在寻找和阅读其他帖子IEnumerable vs IQueryable vs IList,但我仍然不明白这个特殊问题.

Ale*_*kov 9

返回适合您特定情况的最小接口.

通常IEnumerable<T>是足够的,并提供更多的灵活性,但如果你发现自己需要.ToList()经常使用(并且有正当理由)返回IList<T>甚至List<T>.

笔记

  • IEnumerable<T>允许更容易的懒惰评估和单元测试(因为它小于IList- 所以尽量坚持下去.
  • 你的样本没有显示有效的调用理由.ToList()- 结合IEnumerable<T>直到你知道你究竟想要什么甚至可以让你获得更好的表现(即如果经过几次检查你决定只需要一个元素但ToList会迫使你获取10000).

  • @Cody就你个人而言,我会从你的存储库层返回IEnumerable.您没有理由在IMO提供的代码中使用ToList (2认同)