2013-02-20 37 views
11

假设有两个仓库接口实现工作和存储库模式的单位的做法:建议使用ServiceStack.ORMLite

interface IFooRepository 
{ 
    void Delete(int id); 
} 

interface IBarRepository 
{ 
    void Delete(int id); 
} 

而像一个IUnitOfWork接口:

interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    void Rollback(); 
} 

什么是最好的做法使用ServiceStack.ORMLite实现这些接口,以便用户可以使用它们,如

MyFooRepository.Delete(4); 
// if an Exception throws here, Bar won't be deleted 
MyBarRepository.Delete(7); 

或者

using (var uow = CreateUnitOfWork()) 
{ 
    MyFooRepository.Delete(4); 
    MyBarRepository.Delete(7); 
    uow.Commit(); //now they are in an transaction 
} 
+0

我会建议避免使用的UOW尽可能多可能。通过这样的开放式交易通常是一个非常糟糕的设计。 (在以前的版本中,我自己是犯这个东西的) – 2014-09-08 15:27:00

回答

9

不知道你需要存储库+的UnitOfWork模式,但我认为有在ServiceStack + OrmLite一些替代性的解决方案,让您的代码“干”,你需要引入任何模式之前(尤其是如果你”主要是寻求交易/回滚支持)。下面的东西就是我要开始的地方。

public class Foo //POCO for data access 
{ 
    //Add Attributes for Ormlite 
    public int Id { get; set; } 
} 

public class Bar //POCO for data access 
{ 
    //Add Attributes for Ormlite 
    public int Id { get; set; } 
} 

//your request class which is passed to your service 
public class DeleteById 
{ 
    public int Id { get; set; } 
} 

public class FooBarService : MyServiceBase //MyServiceBase has resusable method for handling transactions. 
{ 
    public object Post(DeleteById request) 
    { 
     DbExec(dbConn => 
        { 
         dbConn.DeleteById<Foo>(request.Id); 
         dbConn.DeleteById<Bar>(request.Id); 
        }); 

     return null; 
    } 
} 

public class MyServiceBase : Service 
{ 
    public IDbConnectionFactory DbFactory { get; set; } 

    protected void DbExec(Action<IDbConnection> actions) 
    { 
     using (var dbConn = DbFactory.OpenDbConnection()) 
     { 
      using (var trans = dbConn.OpenTransaction()) 
      { 
       try 
       { 
        actions(dbConn); 
        trans.Commit(); 
       } 
       catch (Exception ex) 
       { 
        trans.Rollback(); 
        throw ex; 
       } 
      } 
     } 
    } 
} 

一些参考文献...

https://github.com/ServiceStack/ServiceStack.RedisWebServices - 上面的代码被从这个例子

https://groups.google.com/forum/#!msg/servicestack/1pA41E33QII/R-trWwzYgjEJ改性 - 谈层在ServiceStack

http://ayende.com/blog/3955/repository-is-the-new-singleton - Ayende Rahien(NHibernate的核心贡献者)在存储库模式

+1

patternalist,似乎是一个好的模式 – GorillaApe 2013-10-04 06:32:32

+0

如果你需要特殊/复杂的逻辑sql你会把它们放在哪里? – GorillaApe 2013-10-04 07:42:50

+0

我想你可以在发送到DbExec方法的动作/函数中尽可能多地执行特殊/复杂的逻辑sql。也可以编写一个独立的函数并将其传递给该块(动作/函数)。此外,这个例子可能不是复杂情况下的最佳方法。 – paaschpa 2013-10-04 18:22:11