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

时间:2011-06-08 15:13:29

标签: c# entity-framework repository-pattern

使用包含多个大型主表的初始项目时,存储库模式似乎运行良好。

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

E.g。

CustomerAddress Record具有以下子表:

- >县

- >国家

- > CustomerType

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

有没有最好的做法/更有效的方法呢?

作为一个例子,假设您有一个主CustomerAddress存储库,我猜是“聚合根”,它继承了基本repo接口的主要CRUD操作。

之前我已经缩短了聚合根,并直接进入了这些类型的表格。

e.g。

public Customer GetCustomerById(int id)
{
  return Get(id);
}

public IEnumerable<Country> GetCountries()
{
  return _ctx.DataContext.Countries.ToList();
}

等...

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

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


更通用的说明,为需求而构建

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

示例:

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

答案 2 :(得分:0)

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

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

2)编写那些实现

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

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

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

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

答案 3 :(得分:0)

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

回购之间的共享,较小的回购是问题(是需要的),我很欣赏这个问题/问题,但是伙计们呢?在这个帖子上引导我做好每张桌子1个回购,包括有可能有一个服务层,虽然他们没有提供任何这方面的例子,我还没有尝试了这一点(目前我的做法,无论好坏,都是拥有更大的回购份额或实例化它需要的更小的回购):

One repository per table or one per functional section?