C# 使用表无关方法实现通用存储库

C# 使用表无关方法实现通用存储库,c#,npoco,C#,Npoco,我正在重构一个持久性层,以使用真正的通用存储库,并希望尽量减少在不同表上执行的类似查询的数量——想想像表a、b或c中的get by id这样的东西,其中查询只因表而异 到目前为止,我的存储库如下所示: 公共接口假定 { 无效插入实体; 无效更新实体; } 公共类BaseRepository:IRepository,其中tenty:class { ///省略的东西。。。 公共空插入实体 { _插入性; } 公共void updateEntity实体 { _更新性; } } 公共接口IDerived

我正在重构一个持久性层,以使用真正的通用存储库,并希望尽量减少在不同表上执行的类似查询的数量——想想像表a、b或c中的get by id这样的东西,其中查询只因表而异

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

公共接口假定 { 无效插入实体; 无效更新实体; } 公共类BaseRepository:IRepository,其中tenty:class { ///省略的东西。。。 公共空插入实体 { _插入性; } 公共void updateEntity实体 { _更新性; } } 公共接口IDerivedRepository:IRepository { //定义在基IRepository上找不到的接口方法 } 公共类派生存储库:BaseRepository、iDrivedRepository { //实现在IDerivedRepository上定义的方法,并从BaseRepository继承Insert和Update } 这可以很好地工作,因为任何新的存储库都可以继承在基本repo上定义的方法,这些方法是类型无关的,因为我可以简单地发送一个实体,我的ORM NPoco管理插入/更新

我想对其进行扩展,以允许对简单的get/fetch类型方法使用泛型的基本定义-get by id或简单计数就是明显的例子。目前,我在适当的存储库中实现了这些方法,因此在单独的存储库中使用多个存储库方法来调用基本相同的代码

下面的示例是简化的_dbmanages scope等,但强调了我试图避免的内容-表和返回类型不同的重复GetById方法

公共类派生存储库:BaseRepository、IderivedRepository { 公共getByidit id{ 从TableA返回_db.Fetchselect*,其中id=@0,id; } } 公共类派生存储库B:BaseRepository,IDerivedBRepository { 公共B getByidit id{ 从TableB返回_db.Fetchselect*,其中id=@0,id; } } 公共类派生的存储库C:BaseRepository,IDerivedCRepository { 公共C getByidit id{ 从TableC返回_db.Fetchselect*,其中id=@0,id; } } 有可能吗?我该怎么做?

下面的BaseRepository实现默认使用类型名作为表名,但如果需要,允许使用与类型名不同的自定义表名

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private readonly string tableName;

    public BaseRepository() : this(typeof(TEntity).Name)
    {

    }

    public BaseRepository(string tableName)
    {
        this.tableName = tableName;
    }

    public TEntity GetById(int id)
    {
        return _db.Fetch<TEntity>($"select * from Table{tableName} where id = {id}");
    }
}

您不需要表名,这样就可以了

    return _db.Single<TEntity>("where id = @id", id);  //Or Fetch
您可以这样做,让NPoco处理SQL。您还可以将其用于保存或删除

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

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

你说,目前,我在适当的存储库中实现了这些,因此最终使用了多个存储库方法-因此请向我们展示这些代码。当然-更新了问题这只是我想到的一种方法。。。您可以在TEntity中定义两个属性,例如TableName和Parameter,并使用字符串插值select*from{entity.TableName},其中{entity.Paramater}=etc…这与我最后所做的非常相似-我的POCO用NPoco属性修饰,例如,我可以通过一些反射魔法获得表名,并在sql字符串中使用它。似乎在做这项工作。