不暴露 IQueryable 不违反 OC 原则

Not exposing IQueryable and not violating OC principle

最近几天我正在阅读有关存储库模式的信息,每个人都在谈论它,但不会像这样从存储库中公开 IQueryable(例如 here and here):

public interface ICustomersRepository
{
    IQueryable<Customer> Customers{ get; }
}

并且为避免这种情况被大量开发人员所接受。

但是当涉及到从 UI 中过滤大量数据和自定义过滤器时(例如具有超过 10 个过滤器选项的报告,用于搜索超过 100 万条记录的数据)是 IQueryable 吗?

特别是当有框架并且其他低级别开发人员正在使用存储库开发自定义报告 时。他们不能总是为此目的使用 GetAll。

因此,正如在 this or this 等其他主题中提到的,我应该为存储库中的每份报告提供方法,并且它们应该 return IEnumerable。以下是我不清楚的地方:

如果我有一个新报告,我必须为此更改我的存储库并添加一个新方法。如果我更改我的存储库,我就违反了 Open/Close principle.

这是我的问题:我不想公开 Iqueryable,另一方面,我不想为每个报告更改我的存储库。

存储库是对数据访问层 (DAL) 的抽象。在 Java 中,它们也被称为 DAO(数据访问对象)。因此,在存储库中公开 IQueryable<T> 是不好的做法,因为这个原因,您将 LINQ 查询绑定到客户端代码。

因此,要修复它,您应该创建一个对象,该对象将遵循命令模式以及您支持的所有过滤选项。然后 return 一个 List<T> 或任何你想使用的排序集合(也许 IList<T> 更合适)。

一个例子

class BookFilter
{
    public string NameStartsWith { get; set; }
    public string ISBN { get; set; }
    public DateTime PublishedAfter { get; set; }
    // ....
}

public interface IBookRepository  
{
    IList<Book> Filter(BookFilter filter);
}