不暴露IQueryable并且不违反OC原则

时间:2017-01-04 05:52:01

标签: c# entity-framework repository-pattern unit-of-work

过去几天我正在阅读有关存储库模式的内容,而且每个人都在谈论它并没有像这样从存储库中公开IQueryable(如herehere):

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

大量的开发人员都接受了这一点来避免这种情况。

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

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

正如在thisthis等其他线程中所提到的,我应该为我的存储库中的每个报告提供方法,并且它们应该返回IEnumerable。以下是我不清楚的事情:

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

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

1 个答案:

答案 0 :(得分:0)

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

因此,要修复它,您应该创建一个对象,该对象将遵循命令模式以及您支持的所有过滤选项。然后返回您要使用的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);
}