我正在尝试使用ORMLite实现Repository模式。我最初开始时:
public List<Todo> GetByIds(long[] ids)
{
using (IDbConnection dbConn = dbFactory.OpenDbConnection())
{
return dbConn.Ids<Todo>(ids).ToList();
}
}
但是在我的Repository中的每个方法下都有这个似乎有点重复?所以我创建了一个数据上下文类,我的所有存储库都继承自:
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进行数据访问时所提出的其他模式。
答案 0 :(得分:8)
我不会对存储库中的连接强类型DialectProvider和配置进行硬编码。相反,我会做一些类似于ServiceStack的基础Service类的事情,例如:
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
所在的位置,即在您的主机项目的IOC注册中。在ServiceStack中,这是AppHost.Configure()
:
container.Register<IDbConnectionFactory>(c =>
OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["AppDb"].
ConnectionString, SqlServerDialect.Provider);
container.RegisterAutoWired<Repository>().ReusedWithin(ReuseScope.None);
答案 1 :(得分:2)
我知道这是一个老问题,但我认为我已经填上了。我的服务访问IGenericRepository<T>
访问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);
OrmLite的IDatabaseContext
:
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);
}
}
}
效果很好。