存储库模式的最佳实践是什么 – 每个表的repo?

在处理具有多个大型主表的初始项目时,存储库模式似乎运行良好。

然而,随着项目的发展,它似乎有点不灵活。 假设您有很多子表挂在主表上,您是否需要每个表的存储库?

例如

CustomerAddress Record具有以下子表:

– >县

– >国家

– > CustomerType

在UI上,需要显示3个下拉列表,但是为上面的每个表编写一个存储库,选择下拉列表的数据会有点繁琐。

这样做是否有最佳实践/更有效的方法?

举个例子说你有一个主CustomerAddress存储库,我猜是’聚合根’,它inheritance了基础repo接口的主要CRUD操作。

以前我已经缩短了聚合根,直接进入了这些类的表的上下文。

例如

public Customer GetCustomerById(int id) { return Get(id); } public IEnumerable GetCountries() { return _ctx.DataContext.Countries.ToList(); } 

等等…

但有时它感觉不对,因为国家不是客户的一部分,但我觉得我需要将其添加到某些东西而不必为每个表创建数以万计的回购。 每张桌子的回购肯定对我来说也不合适。

我肯定不会为每个表创建一个存储库。 相反:我将定义一个适用于每个表的通用存储库。 通过这样做,您可以节省大量代码,当您在该类上实现IQueryable时,它将允许您对其使用LINQ查询,并且您可以隐藏抽象背后的O / RM框架,这样您就可以有效地编写unit testing。 我写了一篇关于此的文章,请参阅伪造LINQ提供程序 。

首先,您发布的代码不是存储库模式。 集合在哪里接口? 如果它是一个聚合,它应该只返回聚合类型。

存储库模式在能够选择不同类型时不会提供很大的灵活性。 存储库模式遵循一个集合接口(insert / add / update / delete / get / etc),镜像内存中的东西,它通常只检索类型。 因此,如果您要使用存储库模式,则需要选择所有CustomerAddresses,然后*过滤掉这些国家/地区。 我建议你转移到一个不同的模式,这允许更多的灵活性,即DAO。

如果总是通过CustomerAddress维护这些内容,那么切换模式并创建一个DAO类,为您需要的其他类型的东西提供其他一些getter。


在更通用的说明中, 构建需求

从不盲目创建存储库类,这是一个维护噩梦。 我唯一一次争论每个桌面的回购是当你做CMS之类的事情,并且需要能够创造一切。

例:

因此,您有一个CustomerAddress,它将客户和国家/地区联系在一起,但您还有其他一些需要能够CRUD国家/地区的流程。 因此,您需要*存储库来操作国家/地区,如果您正在关注DRY,您不希望有重复的逻辑来操纵国家/地区。 您将拥有使用Country存储库的Customer Respotitory。

我在这里回答我自己的问题,因为虽然建议肯定有用,但我觉得我有更好的解决方案。 虽然我没有为每个表创建底层存储库,因为我有一个带接口的通用存储库基类(Get,Add,Remove),我仍然需要:

1)编写接口以访问任何专门的方法(通常这些是查询)

2)编写这些实现

当我想要检索的是一个国家列表或一些用于填充下拉列表的简单类型时,我不一定要这样做。 如果您有10个引用类型表,请考虑所需的工作量。

我决定做的是创建一个名为SimpleRepo的新类,其中包含ISimpleRepo接口,它暴露了1-2种方法。 虽然我通常不喜欢将IQueryable接口暴露在repo i / f类之外,但我不介意这里因为我想提供灵活性。 我可以简单地公开一个提供灵活性钩子的’Query()’方法。 我可能需要这个来专门订购或过滤。

每当服务需要使用一些简单数据时,都会传入ISimple 接口,其中T是表/类。

我现在避免为这些简单的数据片段创建接口/类的需要。 想什么?

回答提问者自己的回答 :这对我来说没有意义; 虽然你可能仍然有一个很好的用例,但我没有关注。 第1点和第2点…如果你需要专门的方法,那么看起来它们属于他们自己的回购。 第2点:是的,这需要实施。

在回购之间共享,较小的回购是问题(是需要的),我确实很感谢这个问题/问题,但是这个主题上的伙伴们让我在每张桌子上有1个回购,包括有可能服务层’,虽然他们没有提供任何这方面的例子,我还没有尝试过(目前我的做法,无论好坏,都是拥有更大的回购份额或实例化它需要的更小的回购) :

每个表一个存储库或每个function部分一个?