C# 不公开不可公开且不违反OC原则
过去几天我一直在阅读关于存储库模式的文章,每个人都在谈论它,不要像这样从存储库中公开IQueryable(如和):C# 不公开不可公开且不违反OC原则,c#,entity-framework,repository-pattern,unit-of-work,C#,Entity Framework,Repository Pattern,Unit Of Work,过去几天我一直在阅读关于存储库模式的文章,每个人都在谈论它,不要像这样从存储库中公开IQueryable(如和): 公共接口ICCustomersRepository { IQueryable客户{get;} } 为了避免这种情况,很多开发人员都接受了这一点 但是,当涉及到从UI过滤大量数据和自定义过滤器时(比如一个包含10个以上过滤器选项的报表,用于搜索超过100万条记录的数据),IQueryable吗 尤其是当有一个框架,而其他低级开发人员正在使用存储库开发自定义报告时。他们不能总是使用G
公共接口ICCustomersRepository
{
IQueryable客户{get;}
}
为了避免这种情况,很多开发人员都接受了这一点
但是,当涉及到从UI过滤大量数据和自定义过滤器时(比如一个包含10个以上过滤器选项的报表,用于搜索超过100万条记录的数据),IQueryable吗
尤其是当有一个框架,而其他低级开发人员正在使用存储库开发自定义报告时。他们不能总是使用GetAll来实现这一目的
因此,正如在其他线程(如或)中提到的,我应该为存储库中的每一个报告提供方法,并且它们应该返回IEnumerable。我不清楚的是:
如果我有一个新报告,我必须为此更改我的存储库并添加一个新方法。如果我更改了存储库,我就违反了规则
这是我的问题:我不想公开Iqueryable,另一方面,我也不想为每个报表更改我的存储库。存储库是对数据访问层(DAL)的抽象。在Java中,它们也称为DAOs(数据访问对象)。因此,在存储库中公开
IQueryable
是一种糟糕的做法,因为这个原因,您将LINQ查询绑定到客户机代码
因此,要修复它,您应该创建一个对象,该对象将遵循命令模式以及您支持的所有过滤选项。然后返回一个列表
或任何要使用的已排序集合(可能IList
更合适)
一个例子
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);
}
类书籍过滤器
{
具有{get;set;}的公共字符串名称开始
公共字符串ISBN{get;set;}
public DateTime PublishedAfter{get;set;}
// ....
}
公共接口IBookRepository
{
IList过滤器(BookFilter过滤器);
}
感谢您的回复,正如您所说,对于每份报告,我都应该更改存储库?因为客户总是要求一份新的报告,而我应该更改我的存储库,我认为这是一种暴力行为,如果你所做的是报告,那么开放-关闭原则可能不是一个舒适的选择。我在回答你问的案子。尽管如此,您展示的是一个需求发生变化的场景,BookFilter也会相应地改变,并支持以前不支持的新过滤器。与存储库模式保持距离,如果您正在做的是报告,您可能会选择不直接使用iqeryable
,如果报告可能会更改或增长,则可能会选择更多。谢谢您,这正是我对更新我的问题以供将来澄清的方式感到困惑的原因。不要返回iqeryable,但是拿一个可以用作过滤器的。例如,public SomeType[]Get(iqeryable filter)
这是一个易于使用的var result=someTypeRepo.Get(x=>x.Id>0)
。谢谢你,这实际上很容易工作。你也可以使用iqeryables来表达你想要包含在结果中的导航属性,这也会像我现在做的一样有帮助,但毕竟我必须返回所有数据进行过滤
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);
}