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このようにして、本来あるべき場所、つまりホストプロジェクトの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

IGenericRepository<T>私はこれが古い質問であることを知っていますIDatabaseContextが、私はチップインすると思っていましSystem.Data.IDbConnectionIDbConnectionFactory.

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 に答える