使用ServiceStack.ORMLite实现工作单元和存储库模式的最佳实践

使用ServiceStack.ORMLite实现工作单元和存储库模式的最佳实践,
Warning: implode(): Invalid arguments passed in /data/phpspider/zhask/webroot/tpl/detail.html on line 45
,,假设有两个存储库接口: interface IFooRepository { void Delete(int id); } interface IBarRepository { void Delete(int id); } 以及一个IUnitOfWork界面,如: interface IUnitOfWork : IDisposable { void Commit(); void Rollback(); } 使用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);


我不确定您是否需要Repository+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;
                }
            }
        }
    }
} 
用于数据访问的公共类Foo//POCO { //为Ormlite添加属性 公共int Id{get;set;} } 用于数据访问的公共类Bar//POCO { //为Ormlite添加属性 公共int Id{get;set;} } //传递给服务的请求类 公共类DeleteById { 公共int Id{get;set;} } 公共类FooBarService:MyServiceBase//MyServiceBase具有用于处理事务的可恢复方法。 { 公共对象Post(DeleteById请求) { DbExec(dbConn=> { dbConn.DeleteById(request.Id); dbConn.DeleteById(request.Id); }); 返回null; } } 公共类MyServiceBase:服务 { 公共IDbConnectionFactory数据库工厂{get;set;} 受保护的void DbExec(操作) { 使用(var dbConn=DbFactory.OpenDbConnection()) { 使用(var trans=dbConn.OpenTransaction()) { 尝试 { 行动(dbConn); trans.Commit(); } 捕获(例外情况除外) { trans.Rollback(); 掷骰子; } } } } } 一些参考资料

-根据该示例修改了上述代码

-讨论ServiceStack中的层


-Ayende Rahien(NHibernate core contributor)在存储库模式上

如果您需要特殊/复杂的逻辑sql,您会将它们放在哪里?我想您可以在发送到DbExec方法的操作/函数中执行任意多的特殊/复杂逻辑sql。还可以编写一个独立函数并在块内传递它(操作/函数)。此外,这个例子可能不是解决复杂情况的最佳方法。我建议尽量避免使用UOW。像这样传递一个开放的事务通常是一个非常糟糕的设计。(在之前的修订版中,我自己也犯了这种错误)
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;
                }
            }
        }
    }
}