加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 存储库模式最佳实践

发布时间:2020-12-16 00:39:41 所属栏目:asp.Net 来源:网络整理
导读:所以我正在应用程序中实现存储库模式,并在我对模式的理解中遇到了两个“问题”: 查询 – 我已经阅读了使用存储库时不应该使用IQueryable的响应。但是,很明显,您希望在每次调用方法时都不会返回完整的对象列表。应该实施吗?如果我有一个名为List的IEnume
所以我正在应用程序中实现存储库模式,并在我对模式的理解中遇到了两个“问题”:

>查询 – 我已经阅读了使用存储库时不应该使用IQueryable的响应。但是,很明显,您希望在每次调用方法时都不会返回完整的对象列表。应该实施吗?如果我有一个名为List的IEnumerable方法,IQueryable的一般“最佳做法”是什么?应该/不应该有什么参数?
>标量值 – 最好的方法(使用Repository模式)返回单个标量值,而不必返回整个记录?从性能的角度来看,在整行上返回一个标量值是否更有效?

解决方法

严格来说,Repository提供了收集/放置域对象的集合语义。它为您的实现实现(ORM,手动,模拟)提供了一个抽象,以便域对象的消费者与这些细节脱钩。在实践中,存储库通常抽象对实体的访问,即具有身份的域对象,通常是持久的生命周期(在DDD风格中,存储库提供对聚合根的访问)。

存储库的最小接口如下:

void Add(T entity);
void Remove(T entity);
T GetById(object id);
IEnumerable<T> Find(Specification spec);

虽然您会看到命名差异和添加Save / SaveOrUpdate语义,但上述是“纯粹”的想法。你得到ICollection添加/删除成员和一些查找器。如果您不使用IQueryable,您还将在存储库中看到finder方法,如:

FindCustomersHavingOrders();
FindCustomersHavingPremiumStatus();

在这个上下文中使用IQueryable有两个相关的问题。首先是以域对象的关系形式向客户泄露实施细节的可能性,即违反“德米特法”的行为。第二个是,存储库获取可能不属于域对象存储库的责任,例如,找到相对于所请求的域对象少于相关数据的投影。

另外,使用IQueryable’打破’模式:具有IQueryable的存储库可能或可能不提供对“域对象”的访问。 IQueryable为客户端提供了关于最终执行查询时将实现什么的许多选项。这是关于使用IQueryable的争论的主要内容。

关于标量值,您不应该使用存储库来返回标量值。如果你需要一个标量,你通常会从实体本身获得。如果这听起来效率不高,那么您可能不会注意到,这取决于您的负载特性/要求。在需要域对象的备用视图的情况下,由于性能原因或需要合并来自多个域对象的数据,您有两种选择。

1)使用实体的存储库查找指定的实体,并将项目/映射到平坦化视图。

2)创建一个专用于返回一个新的域类型的finder界面,该域类型封装了您需要的平面化视图。这不会是存储库,因为不会有Collection语义,但它可能会使用封面下的现有存储库。

如果您使用“纯”存储库访问持久化实体,需要考虑的一件事是,您会损害ORM的一些优点。在“纯”实现中,客户端无法提供如何使用域对象的上下文,所以您不能告诉存储库:“嘿,我只是要更改customer.Name属性,所以不要麻烦得到那些渴望加载的参考。另一方面,问题是客户是否应该知道这些东西。这是一把双刃剑。

就使用IQueryable而言,大多数人似乎很乐意通过“打破”模式来获得动态查询组合的好处,特别是像分页/排序这样的客户端职责。在这种情况下,您可能有:

Add(T entity);
Remove(T entity);
T GetById(object id);
IQueryable<T> Find();

然后,您可以删除所有这些自定义Finder方法,这真正使您的查询需求增长的Repository变得混乱。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读