【问题标题】:How to implement Repository pattern efficiently with huge dataset? (Paging, etc.)如何使用庞大的数据集有效地实现存储库模式? (分页等)
【发布时间】:2016-03-21 21:50:37
【问题描述】:

我正在查看 Microsoft 给出的这个示例,我完全明白他们想要做什么:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

我的问题是:在进行分页或处理大型数据集(数百万或更多记录)时,如何有效地实现这一点?我阅读此代码的方式是,每次您从存储库中调用 GetStudents 时,它都会列出整个数据集。您如何使用存储库有效地实现搜索、排序和分页(我正在有效地定义,因为在应用程序中不必查询所有行来执行过滤/分页/排序操作)?在我的特殊情况下,我正在谈论实体框架。我过去曾使用 IQueryable 进行高效查询,但我看不到使用存储库模式生成高效存储查询的方法。请帮忙!

【问题讨论】:

  • 他们在过滤器应用到IQueryable之后执行ToList,因此只有过滤后的结果集从数据库返回。
  • 您可能会通过编写自定义调整以过滤/分页数据库中的数据集的存储过程来获得最佳性能。您仍然可以使用存储库模式,只是您不会使用 EF 来自动生成数据库调用。
  • @GertArnold 有时过滤的结果集仍然是一百万条记录 :-)
  • 不适用于分页,它们也适用。
  • @GertArnold 他们也适用的分页是什么意思?我错过了什么吗??

标签: asp.net-mvc entity-framework design-patterns


【解决方案1】:

阅读您提到的文章,您应该删除 .ToList()。这将返回一个 IQueryable 女巫将“懒惰调用”您的数据库。

正如示例中所说:

var students = from s in context.Students
               select s;

重点是:当您拥有大型存储库时,永远不要查询整个内容。始终使用 WHERE 标准。 分页结果可能在内存(应用程序)或数据库中完成。这实际上取决于您的环境和需求。

【讨论】:

  • 我知道我可以返回一个 IQueryable... 问题是因为它是一个 IQueryable 不能与对 IQueryable 数据执行操作的 C# 函数一起使用,例如 String.Join()因为该表达式无法转换为存储表达式(即 SQL 服务器可以理解 String.Join())。此外,IQueryable 在技术上公开了可能无法实现的方法,因此它是一个泄漏的抽象。
【解决方案2】:

如果您查看链接到的页面底部,您会看到过滤示例:

public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")

Get 函数在使用 toList() 实现查询之前应用过滤器。如果要添加分页,您可以添加参数以在具体化之前将 .Top() 和 .Skip() 应用于您的查询。

【讨论】:

    猜你喜欢
    • 2014-03-12
    • 2021-03-10
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多