与dapper的通用存储库

Bry*_*yan 9 c# sql asp.net-mvc dapper

我试图用dapper构建一个通用的存储库.但是,我在实现CRUD操作时遇到了一些困难.

这是存储库中的一些代码:

 public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    internal IDbConnection Connection
    {
        get
        {
            return new SqlConnection(ConfigurationManager.ConnectionStrings["SoundyDB"].ConnectionString);
        }
    }

    public GenericRepository(string tableName)
    {
        _tableName = tableName;
    }

    public void Delete(TEntity entity)
    {
        using (IDbConnection cn = Connection)
        {

            cn.Open();
            cn.Execute("DELETE FROM " + _tableName + " WHERE Id=@ID", new { ID = entity.Id });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我的delete-method将TEntity作为参数,它是类类的参数.

我从我的UserRepository调用我的Delete方法,如下所示:

public class UserRepository : GenericRepository<User>, IUserRepository
{
    private readonly IConnectionFactory _connectionFactory;

    public UserRepository(IConnectionFactory connectionFactory) : base("User")
    {
        _connectionFactory = connectionFactory;
    }

    public async Task<User> Delete(User model)
    {
        var result = await Delete(model);
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我无法entity.Id在我的通用存储库中的Delete-opration中编写.我收到一个错误.那么如何轻松实现这样的CRUD操作呢?

这是错误消息:

TEntity does not contain a definition of "Id" and no extension method "Id" accepting a argument of type "TEntity" could be found
Run Code Online (Sandbox Code Playgroud)

Igo*_*gor 8

定义一个这样的界面.

public interface ITypeWithId {
    int Id {get;}
}
Run Code Online (Sandbox Code Playgroud)

并确保您的User类型实现该接口.

现在将它作为通用约束应用于您的类.

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class, ITypeWithId
Run Code Online (Sandbox Code Playgroud)

如果您的类型存储在存储库中但DO不具有Id属性,则使您的删除类型约束特定于方法而不是类.这将允许您仍然使用相同的存储库类型,即使类型可能键入其他内容,如字符串或复合(多)键.

public void Delete<T>(T entity) where T : class, ITypeWithId
{
    using (IDbConnection cn = Connection)
    {

        cn.Open();
        cn.Execute("DELETE FROM " + _tableName + " WHERE Id=@ID", new { ID = entity.Id });
    }
}
Run Code Online (Sandbox Code Playgroud)


bbs*_*nbb 5

请不要这样做!您的通用存储库增加的混乱多于价值。它是脆弱的代码(_tableName的字符串文字,id参数上的无效强制转换错误),并引入了一个巨大的安全漏洞(通过_tableName进行sql注入)。如果选择了Dapper,那是因为您想控制自己的sql,因此生成发送给Dapper的sql没有任何意义。