使用与表无关的方法来实现通用存储库

时间:2019-03-05 23:41:42

标签: c# npoco

我正在努力重构一个持久层,以使用真正的通用存储库,并希望最大程度地减少在不同表上执行的类似查询的数量-想想从表a,b或c中通过id获取的事情,其中查询仅因表而异。

到目前为止,我的存储库如下:

public interface IRepository<T>
{
    void Insert(T entity);
    void Update(T entity);
}

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    /// ctor stuff omitted ...

    public void Insert(TEntity entity)
    {
        _db.Insert<TEntity>(entity);
    }

    public void Update(TEntity entity)
    {
        _db.Update<TEntity>(entity);
    }
}

public interface IDerivedRepository : IRepository<MyEntity>
{
    // defines interface methods not found on the base IRepository
}

public class DerivedRepository : BaseRepository<MyEntity>, IDerivedRepository
{
    // implements methods defined on IDerivedRepository, and inherits Insert and Update from BaseRepository
}

这很好用,因为任何新存储库都可以继承基本存储库上定义的方法,这些方法与类型无关,因为我可以简单地发送实体,而我的ORM(NPoco)管理插入/更新。

我想扩展它以允许简单的get / fetch类型方法的通用基本定义-通过id或简单的计数来获取是显而易见的示例。目前,我在适当的存储库中实现了这些,因此最终得到了多个存储库方法(在单独的存储库中),它们调用了基本上相同的代码。

下面的示例已简化(_db管理范围等),但强调了我要避免的事情-重复的GetById方法,其中表和返回类型不同

public class DerivedRepositoryA : BaseRepository<A>, IDerivedARepository
{
    public A GetById(int id) {
        return _db.Fetch<A>("select * from TableA where id = @0", id);
    }
}

public class DerivedRepositoryB : BaseRepository<B>, IDerivedBRepository
{
    public B GetById(int id) {
        return _db.Fetch<B>("select * from TableB where id = @0", id);
    }
}

public class DerivedRepositoryC : BaseRepository<C>, IDerivedCRepository
{
    public C GetById(int id) {
        return _db.Fetch<C>("select * from TableC where id = @0", id);
    }
}

有可能吗,我该怎么办?

2 个答案:

答案 0 :(得分:1)

下面的#pragma once实现默认情况下使用类型名作为表名,但是允许自定义表名,如果需要,该名称与类型名不同。

BaseRepository<TEntity>

答案 1 :(得分:0)

您不需要表名,这可以工作

    return _db.Single<TEntity>("where id = @id", id);  //Or Fetch

您可以执行以下操作,让NPoco处理SQ​​L。您也可以将其用于Save ()或Delete ()

    public T GetByID<T>(Int32 ID)
    {
        try
        {
            if (ID == 0)
                throw (new ArgumentNullException("ID cannot be 0"));

            return _db.SingleOrDefaultById<T>(ID);
        }
        catch { throw; }
    }