7

我正在尝试使用 ORMLite 实现存储库模式。我最初是这样开始的:

public List<Todo> GetByIds(long[] ids)
{
    using (IDbConnection dbConn = dbFactory.OpenDbConnection())
    {
        return dbConn.Ids<Todo>(ids).ToList();
    }
}

但是在我的存储库中的每种方法下都有这个似乎有点重复?所以我创建了一个数据上下文类,我的所有存储库都继承自:

public class TodoRepository : DataContext

这是那个DataContext类:

public class DataContext
{
    protected OrmLiteConnectionFactory dbFactory = new 
OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
ConnectionString, SqlServerOrmLiteDialectProvider.Instance);

    protected IDbConnection dbConn;

    public DataContext()
    {
        dbConn = dbFactory.OpenDbConnection();
    }
}

然后我只需在我的方法中执行此操作:

public List<Todo> GetByIds(long[] ids)
{
    return dbConn.Ids<Todo>(ids).ToList();
}

我只是好奇这是否是一个好的设计模式,以及其他人在使用存储库模式通过 ORMLite 进行数据访问时提出了什么。

4

2 回答 2

8

我不会对存储库中的连接的强类型 DialectProvider 和配置进行硬编码。相反,我会做一些类似于 ServiceStack 的基础服务类的事情,例如:

public class Repository : IDisposable {

    public IDbConnectionFactory DbFactory { get; set; } //injected by IOC

    IDbConnection db;
    IDbConnection Db 
    { 
        get 
        {
            return db ?? db = DbFactory.Open();
        }
    }

    public List<Todo> GetByIds(long[] ids)
    {
        return Db.Ids<Todo>(ids);
    }

    public void Dispose() {
        if (db != null)
            db.Dispose();
    }
}

通过这种方式,您可以初始化IDbConnectionFactory它应该在的位置,即在您的 Host 项目的 IOC 注册中。在 ServiceStack 中,这是在AppHost.Configure()

container.Register<IDbConnectionFactory>(c => 
    OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
        ConnectionString, SqlServerDialect.Provider);

container.RegisterAutoWired<Repository>().ReusedWithin(ReuseScope.None); 
于 2013-01-23T13:51:06.943 回答
3

我知道这是一个老问题,但我想我会加入。我的服务访问 aIGenericRepository<T>访问 a IDatabaseContext(可以是任何使用的东西System.Data.IDbConnection,但在这种情况下是 ServiceStack 的 OrmLite),而后者又使用 ServiceStack 的IDbConnectionFactory

public class GenericRepository<T> : IGenericRepository<T>
    where T : class
{
    private readonly IDatabaseContext _databaseContext;

    public GenericRepository(IDatabaseContext databaseContext)
    {
        _databaseContext = databaseContext;
    }

    public T Get(int id)
    {
        return _databaseContext.Query(db =>
            {
                return db.SingleById<T>(id);
            });
    }

    public async Task<T> GetAsync(int id)
    {
        return await _databaseContext.QueryAsync(async db =>
        {
            return await db.SingleByIdAsync<T>(id);
        });
    }

    // other methods (All, First, etc)
}

IDbConnectionFactory注册为

container.Register<IDbConnectionFactory>(c => 
    OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
        ConnectionString, SqlServerDialect.Provider);

对于IDatabaseContextOrmLite:

public class OrmLiteDatabaseContext : IDatabaseContext
{
    private readonly IDbConnectionFactory _dbConnectionFactory;

    public DatabaseContext(IDbConnectionFactory dbConnectionFactory)
    {
        _dbConnectionFactory = dbConnectionFactory;
    }

    public T Query<T>(Func<IDbConnection, T> query)
    {
        using (var connection = _dbConnectionFactory.OpenDbConnection())
        {
            return query(connection);
        }
    }

    public async Task<T> QueryAsync<T>(Func<IDbConnection, Task<T>> query)
    {
        using (var connection = _dbConnectionFactory.OpenDbConnection())
        {
            return await query(connection);
        }
    }
}

效果很好。

于 2015-04-17T09:24:16.567 回答