c# - 返回 IQueryable<T> 或不返回 IQueryable<T>

标签 c# .net linq-to-sql iqueryable

<分区>

我有一个存储库类,它包装了我的 LINQ to SQL 数据上下文。存储库类是包含所有数据层逻辑(以及缓存等)的业务线类。

这是我的 repo 接口(interface)的 v1。

public interface ILocationRepository
{
    IList<Location> FindAll();
    IList<Location> FindForState(State state);
    IList<Location> FindForPostCode(string postCode);
}

但是为了处理 FindAll 的分页,我正在讨论是否公开 IQueryable 而不是 IList 以简化分页等情况的接口(interface)。

从数据存储库中公开 IQueryable 的优缺点是什么?

非常感谢任何帮助。

最佳答案

优点;可组合性:

  • 来电者可以添加过滤器
  • 调用者可以添加寻呼
  • 来电者可以添加排序
  • 等等

缺点;不可测试性:

  • 您的存储库不再适合进行单元测试;你不能依赖 a:它工作,b:它做什么
    • 调用者可以添加一个不可翻译的函数(即没有 TSQL 映射;在运行时中断)
    • 调用者可以添加一个过滤器/排序,使其像狗一样执行
  • 因为来电者期望 IQueryable<T>为了可组合,它排除了不可组合的实现 - 或者它会强制您为它们编写自己的查询提供程序
  • 这意味着您无法优化/分析 DAL

为了稳定性,我已采取公开IQueryable<T>Expression<...>在我的存储库上。这意味着我知道存储库的行为方式,并且我的上层可以使用模拟而不用担心“实际的存储库是否支持这个?” (强制集成测试)。

我还在用IQueryable<T> etc inside 存储库 - 但不超过边界。我发布了一些 more thoughts on this theme here .将分页参数放在存储库界面上同样容易。您甚至可以使用扩展方法(在接口(interface)上)添加可选分页参数,这样具体类只有 1 个方法要实现,但可能有 2 或 3 个重载可供调用者使用。

关于c# - 返回 IQueryable<T> 或不返回 IQueryable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/718624/

相关文章:

c# - 版本对象错误地比较了两个版本

c# - 从 Using 运算符内的函数返回

c# - 给定当前记录的 ID,这是选择上一条和下一条记录的正确方法吗?

c# - 如何通过一次调用 Azure key 保管库获取所有 secret

C# 命名空间/文件夹 : when is getting too organized/creating too many namespaces not right?

c# - 如何重构看起来相同的方法调用?

c# - 即使在 wpf datagrid 中失去焦点后,单元格仍处于编辑模式

c# - 区分 getter-only 属性和表达式主体属性?

c# - Web 服务 session 在调试时有效,但在发布时无效

.net - LINQ-to-SQL 中的 "Order By"导致性能问题