2011-06-08 69 views
7

当使用几个大型主表进行初始项目时,存储库模式似乎很有效。存储库模式的最佳实践 - 每个表的回购?

但随着项目的发展,它似乎有点不灵活。假设你有大量的子表挂在主表之外,你是否需要每个表的存储库?

E.g.

CustomerAddress记录具有以下子表:

- >县

- >国家

- > CustomerType

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

是否有最佳做法/更有效的方式来做到这一点?

作为一个例子说,你有一个主要的CustomerAddress存储库,我猜是从基本repo接口继承了主CRUD操作的'聚合根'。

之前我已经对聚合根进行了简化,并直接进入了这些表的上下文。

例如

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

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

等等

但有时不感觉权利,因为国家是不是客户的一部分,但我觉得我需要把它钉到东西,而不必为每个表创建大量的回购协议。每张表的回购肯定对我来说也不合适。

+0

好。因为你删除了一个'CustomerAddress',所以'Country'不会因为destroyd而失效。我认为它会继续蓬勃发展。这不是儿童聚合。 – jgauffin 2013-01-14 06:43:45

+0

避免使用ORM存储库;)http:// ayende。com/blog/3955/repository-is-new-singleton – fex 2014-08-11 13:25:13

回答

0

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

1)编写接口访问任何特定的方法(通常这些查询)

2)写那些实现

我并不想这样做,当所有我想要检索的或国家的列表一些简单的类型填充一个下拉菜单。如果您有10个参考类型表,请考虑所需的努力。

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

无论何时服务需要使用一些简单的数据,T>接口的简单接口将被传入,其中T是表/类。

我现在不需要为这些简单的数据创建接口/类。 有什么想法?

0

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

当它能够选择不同的类型时,存储库模式不提供很大的灵活性。存储库模式遵循一个集合接口(插入/添加/更新/删除/ get/etc),镜像内存的东西,它通常只检索类型。因此,如果您要使用存储库模式,则需要选择所有CustomerAddresses,然后*将这些国家过滤掉。我建议你采用不同的模式,即DAO更具灵活性。

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


在一个更通用的音符,建立需要

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

例子:

所以,你有哪些联系在一起一个客户和一个国家CustomerAddress,但你需要能够CRUD国家其他进程。因此,您需要*储存库来操纵国家,如果您遵循DRY,则不需要具有操纵国家的重复逻辑。您将拥有的是使用国家/地区存储库的客户Respotitory。

+0

对不起,我更新了我的代码示例。 – jaffa 2011-06-08 15:28:03

+0

@jaffa我没有看到改变? – Nix 2011-06-08 15:28:37

+0

我改变了函数签名来显示我的GetCustomerById返回一个具体的对象关闭回购,并且这些国家是一个集合对象。 – jaffa 2011-06-08 15:40:01

2

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

+0

我已经为类实现了一个基础知识库类,但是我仍然需要为每个表创建一个专门的具有i/f的回购类。我不明白如何在不执行CountryRepo的情况下将我的viewModel的国家列表传递给我? – jaffa 2011-06-08 15:42:07

+0

如果你看看我指出的文章,你会发现我定义了一个工作单位类,它将所有的存储库保存为属性。添加一个新的存储库意味着只需将新的属性添加到工作单元中,而不是添加新的存储库类。 – Steven 2011-06-08 16:42:37

0

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

在回购之间进行分享,回购是一个小问题(这是需要的),我很欣赏这个问题/问题,但是在这个主题上的家伙们让我对每张表的回购有好处,包括可能性有一个'服务层',尽管他们没有给出任何例子,我还没有尝试过(目前我的做法,无论好坏,一直是有更大的回购份额或实例化较小它需要):

One repository per table or one per functional section?