我遵循了有关带有带有EF CORE的ASP.NET核心的通用存储库模式的教程,
here
例如

   public class Repository<T> : IRepository<T> where T : class
   {
    protected readonly DbContext _dbContext;
    protected readonly DbSet<T> _dbSet;

    public Repository(DbContext context)
    {
        _dbContext = context ?? throw new
         ArgumentException(nameof(context));
        _dbSet = _dbContext.Set<T>();
    }

    public void Add(T entity)
    {
       _dbSet.Add(entity);
    }
   }

由于这是使用EF Core,我们可以使用它的预定义方法通过Add方法插入数据,但是当涉及dapper时,它需要sql查询,那么我如何才能创建适合Dapper的通用接口(interface)呢?

最佳答案

@PathumLakshan提供的示例来自评论。提供的示例以异步方式编写,但是源代码可以同步实现。无论如何,这仅是如何使用Dapper管理基础结构的说明。 Db类提供了一些用于获取数据和执行SQL查询的通用方法。例如,您可以对基本查询使用重载Get<T>(string, object),或者让Get<T>(Func<SqlConnection, SqlTransaction, int, Task<T>>使用让我们说的QueryMultiple。类Repository<Entity>展示了如何查找实体Entity的基本存储库。

Db类:

public class Db : IDb
{
    private readonly Func<SqlConnection> _dbConnectionFactory;

    public Db(Func<SqlConnection> dbConnectionFactory)
    {
        _dbConnectionFactory = dbConnectionFactory ?? throw new ArgumentNullException(nameof(dbConnectionFactory));
    }

    public async Task<T> CommandAsync<T>(Func<SqlConnection, SqlTransaction, int, Task<T>> command)
    {
        using (var connection = _dbConnectionFactory.Invoke())
        {
            await connection.OpenAsync();

            using (var transaction = connection.BeginTransaction())
            {
                try
                {
                    var result = await command(connection, transaction, Constants.CommandTimeout);

                    transaction.Commit();

                    return result;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Logger.Instance.Error(ex);
                    throw;
                }
            }
        }
    }

    public async Task<T> GetAsync<T>(Func<SqlConnection, SqlTransaction, int, Task<T>> command)
    {
        return await CommandAsync(command);
    }

    public async Task<IList<T>> SelectAsync<T>(Func<SqlConnection, SqlTransaction, int, Task<IList<T>>> command)
    {
        return await CommandAsync(command);
    }

    public async Task ExecuteAsync(string sql, object parameters)
    {
        await CommandAsync(async (conn, trn, timeout) =>
        {
            await conn.ExecuteAsync(sql, parameters, trn, timeout);
                return 1;
        });

    public async Task<T> GetAsync<T>(string sql, object parameters)
    {
        return await CommandAsync(async (conn, trn, timeout) =>
        {
            T result = await conn.QuerySingleAsync<T>(sql, parameters, trn, timeout);
            return result;
        });
    }

    public async Task<IList<T>> SelectAsync<T>(string sql, object parameters)
    {
        return await CommandAsync<IList<T>>(async (conn, trn, timeout) =>
        {
            var result = (await conn.QueryAsync<T>(sql, parameters, trn, timeout)).ToList();
            return result;
        });
    }
}

存储库类:
public class Repository<Entity> : IRepository<Entity>
{
    protected readonly IDb _db;

    public Repository(IDb db)
    {
        _db = db ?? throw new
            ArgumentException(nameof(db));
    }

    public async Task Add(Entity entity)
    {
        await _db.ExecuteAsync("INSERT INTO ... VALUES...", entity);
    }

    public async Task Update(Entity entity)
    {
        await _db.ExecuteAsync("UPDATE ... SET ...", entity);
    }

    public async Task Remove(Entity entity)
    {
        await _db.ExecuteAsync("DELETE FROM ... WHERE ...", entity);
    }

    public async Task<Entity> FindByID(int id)
    {
        return await _db.GetAsync<Entity>("SELECT ... FROM ... WHERE Id = @id", new { id });
    }

    public async Task<IEnumerable<Entity>> FindAll()
    {
        return await _db.SelectAsync<Entity>("SELECT ... FROM ... ", new { });
    }
}

可以使用其他通用方法来扩展Db,例如ExecuteScalar,这在存储库中将是需要的。希望能帮助到你。

关于c# - 带有Dapper的.net核心的通用存储库模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52418496/

10-16 12:53