Lak*_*han 6 c# generic-programming repository-pattern dapper asp.net-core
我也跟着上通用的存储库模式教程与ASP.NET核心与EF CORE, 这里 例如
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);
}
}
Run Code Online (Sandbox Code Playgroud)
由于这是使用EF Core,我们只能使用预定义的方法通过Add方法插入数据,但是当涉及dapper时,它需要sql查询,那么我如何才能创建适合Dapper的通用接口?
我们有一个项目,我们有 dapper 通用存储库,但在项目发展之后,我们放弃了通用存储库,以使用 dapper 的真正力量。
我建议直接使用 Dapper,无需通用 CRUD 操作。
为了演示我们所拥有的内容,我将提供一个未准备好用于生产的示例代码,它将为您提供实现您自己的通用存储库的想法。
public abstract class ConnectionBase : IDbConnection
{
protected ConnectionBase(IDbConnection connection)
{
Connection = connection;
}
protected IDbConnection Connection { get; private set; }
// Verbose but necessary implementation of IDbConnection:
#region "IDbConnection implementation"
public string ConnectionString
{
get
{
return Connection.ConnectionString;
}
set
{
Connection.ConnectionString = value;
}
}
public int ConnectionTimeout
{
get
{
return Connection.ConnectionTimeout;
}
}
public string Database
{
get
{
return Connection.Database;
}
}
public ConnectionState State
{
get
{
return Connection.State;
}
}
public IDbTransaction BeginTransaction()
{
return Connection.BeginTransaction();
}
public void Close()
{
Connection.Close();
}
public IDbCommand CreateCommand()
{
return Connection.CreateCommand();
}
public void Dispose()
{
Connection.Dispose();
}
public void Open()
{
Connection.Open();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
通用存储库
public abstract class GenericRepository<T> : IRepository<T> where T : class //EntityBase, IAggregateRoot
{
private readonly string _tableName;
internal IDbConnection Connection
{
get
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["SmsQuizConnection"].ConnectionString);
}
}
public GenericRepository(string tableName)
{
_tableName = tableName;
}
internal virtual dynamic Mapping(T item)
{
return item;
}
public virtual void Add(T item)
{
using (IDbConnection cn = Connection)
{
var parameters = (object)Mapping(item);
cn.Open();
item.ID = cn.Insert<Guid>(_tableName, parameters);
}
}
public virtual void Update(T item)
{
using (IDbConnection cn = Connection)
{
var parameters = (object)Mapping(item);
cn.Open();
cn.Update(_tableName, parameters);
}
}
public virtual void Remove(T item)
{
using (IDbConnection cn = Connection)
{
cn.Open();
cn.Execute("DELETE FROM " + _tableName + " WHERE ID=@ID", new { ID = item.ID });
}
}
public virtual T FindByID(Guid id)
{
T item = default(T);
using (IDbConnection cn = Connection)
{
cn.Open();
item = cn.Query<T>("SELECT * FROM " + _tableName + " WHERE ID=@ID", new { ID = id }).SingleOrDefault();
}
return item;
}
public virtual IEnumerable<T> FindAll()
{
IEnumerable<T> items = null;
using (IDbConnection cn = Connection)
{
cn.Open();
items = cn.Query<T>("SELECT * FROM " + _tableName);
}
return items;
}
}
Run Code Online (Sandbox Code Playgroud)
@PathumLakshan 请求评论提供的示例。提供的示例是以异步方式编写的,但源代码可以同步实现。无论如何,它只是说明如何使用 Dapper 管理基础设施。类Db提供了一些用于获取数据和执行 SQL 查询的通用方法。例如,您可以Get<T>(string, object)对基本查询使用重载,或者Get<T>(Func<SqlConnection, SqlTransaction, int, Task<T>>使用 let say QueryMultiple。类Repository<Entity>展示了如何查看实体的基本存储库Entity。
数据库类:
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;
});
}
}
Run Code Online (Sandbox Code Playgroud)
存储库类:
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 { });
}
}
Run Code Online (Sandbox Code Playgroud)
Db可以使用其他通用方法进行扩展,例如,ExecuteScalar您在存储库中需要它。希望能帮助到你。
| 归档时间: |
|
| 查看次数: |
7202 次 |
| 最近记录: |