【发布时间】:2014-01-30 04:26:30
【问题描述】:
2017 年 3 月 31 日更新
自从这篇文章之后我又学到了一些东西,所以我想给出一个重要的理由,从存储库返回时使用 ToList - 调用 ToList 将(使用 IQueryable 时)在数据库上执行翻译后的 SQL而不是将记录拉入内存然后过滤。我不相信隐式转换为 IEnumerable 或 IList 会这样做。
按照 MSDN 网站上的一些教程,我在我的应用程序中使用了通用存储库层。这个存储层由我的服务层调用,而服务层又由控制器调用。
查看通用存储库,获取数据并通过调用ToList() 返回。但是,该方法的返回类型是IEnumerable,这意味着服务层必须接受IEnumerable,并且在返回到控制器之前,它必须再次在IEnumerable 上调用ToList()。
示例 - 存储库:
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();
}
示例 - 服务层
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();
}
从我所做的阅读来看,最好向控制器提供它需要的对象的List,而不是IEnumerable 或IQueryable。
因此,我认为最好不要返回IEnumerable,而是返回IList。我在这里遗漏了什么吗?为什么 MSDN 团队选择IEnumerable 进行设计并致电ToList?这在哪里有用??在我看来,多次进行这种转换似乎效率低下且毫无意义,尤其是在处理大量数据时。
如果不清楚或已经有答案,我提前道歉,但我一直在搜索和阅读其他帖子 IEnumerable vs IQueryable vs IList,但我仍然不明白这个特定问题。
【问题讨论】:
-
它们是不同的类型/接口,实体框架中的语义也不同(在
IQueryable上调用ToList()会在此时具体化查询,因此如果您对查询有进一步的改进,它们'正在内存中而不是在数据库中完成)。
标签: c# asp.net-mvc performance repository-pattern