2010-06-16 75 views
0

我想知道大多数人如何处理存储库模式,当它涉及多次(有时以事务方式)击中同一个数据库并试图有效地这样做时,同时维护数据库不可知论和使用多个存储库一起。处理多个抽象存储库时有效的数据库访问

假设我们有三个不同实体的存储库; WidgetThingWhatsit。按照正常的解耦设计流程,每个存储库都通过基本接口抽象出来。基础接口将是IWidgetRepository,IThingRepositoryIWhatsitRepository

现在我们有我们的业务层或同等业务(无论您想调用它)。在这个层中,我们有访问各种存储库的类。通常这些类中的方法需要在涉及多个存储库的情况下执行批处理/组合操作。有时一种方法可能会在内部使用另一种方法,而该方法仍然可以独立调用。在这种情况下,什么时候操作需要是事务性的?

例子:

class Bob 
{ 
    private IWidgetRepository _widgetRepo; 
    private IThingRepository _thingRepo; 
    private IWhatsitRepository _whatsitRepo; 

    public Bob(IWidgetRepository widgetRepo, IThingRepository thingRepo, IWhatsitRepository whatsitRepo) 
    { 
     _widgetRepo = widgetRepo; 
     _thingRepo= thingRepo; 
     _whatsitRepo= whatsitRepo; 
    } 

    public void DoStuff() 
    { 
     _widgetRepo.StoreSomeStuff(); 
     _thingRepo.ReadSomeStuff(); 
     _whatsitRepo.SaveSomething(); 
    } 

    public void DoOtherThing() 
    { 
     _widgetRepo.UpdateSomething(); 
     DoStuff(); 
    } 
} 

如何保持我到数据库的访问效率,而不是有开闭 - 开 - 关上MSDTS和诸如此类的连接,并无意调用络绎不绝?如果我的数据库是SQLite之类的,那么像创建嵌套事务这样的标准机制本来就会失败,但是业务层不应该关心这些事情。

你如何处理这些问题? ADO.Net是否提供了简单的机制来处理这个问题,或者大多数人最终将自己的代码封装在ADO.Net中以解决这些类型的问题?

回答

1

基本上你想为此使用UnitOfWork。我个人使用NHibernate,因为他们的ISession接口基本上是一个工作单元,因此它将所有命令一起批量处理,并将它们一起发送到数据库(还有额外的智能和对象状态跟踪,这对此有所帮助)。所以发送到数据库的离散命令的数量将取决于您的ISession的生命周期。在web上下文中,我通常使用Conversation Per Request,这意味着ISession在请求开始时创建,并在请求结束时刷新(发送到数据库)。

根据您是否需要更短或更长的会话来改变会话的生命周期有很大的潜力,并且如果需要,还可以使用可以具有单独生命周期的事务。

+0

我开发了一个数据层,在某种程度上做到了这一点,但是困扰我的是必须使用存储库之外的数据层中的对象。您的建议是一个很好的建议,并且可以让我将这一要求充分抽象出来,使其看起来像是数据层不可知的。 – 2010-06-18 09:58:32

1

想想看,你的抽象库可以在任何数量的数据库来实现:SQLite的,微软SQL服务器,直接文件访问,等等 - 尽管知道他们是来自同一个数据库,这不是合理的“Bob”尝试确保每个存储库都可以相对于其他存储库进行事务处理。

鲍勃也许应该与DoStuffService对话,其中包含您的存储库的具体实现。由于此服务正在创建存储库的具体实现,因此它能够创建适当的事务。然后该服务将负责代表鲍勃安全执行UnitOfWork(感谢,ckramer)。

+0

关于潜在访问多个数据库的好处,将不得不考虑那个。 – 2010-06-18 09:56:55