轻量ORM-SqlRepoEx (十一)扩展
以下为 SqlRepoEx.MsSql.ServiceCollection 代码
public static IServiceCollection AddSqlRepo(this IServiceCollection serviceCollection)
{
serviceCollection.AddTransient<IRepositoryFactory, RepositoryFactory>();
serviceCollection.AddTransient<IStatementFactoryProvider, MsSqlStatementFactoryProvider>();
serviceCollection.AddTransient<IEntityMapper, DataReaderEntityMapper>();
serviceCollection.AddTransient<IWritablePropertyMatcher, WritablePropertyMatcher>();
serviceCollection.AddTransient<ISqlLogger, SqlLogger>();
serviceCollection.AddTransient<IStatementExecutor, MsSqlStatementExecutor>();
return serviceCollection;
}
本质上,其处出现的接口及其实现类,其接口的实现类都是可以自定义的
其中,IEntityMapper,IStatementExecutor两个接口去扩展更具有意义。
其他的高级扩展暂时未开放,不作介绍
我们以Dapper的扩展为例,参照实现,扩展自己定制的功能
一、IEntityMapper 实例映射器接口,其功能主要是 将数据提供者IDataReader中的数据,转换到应用程序可用的数据或数据集中
其接口定义为
/// <summary> /// 实例映射器接口,将IDataReader中的数据转换成TEntity类型实例 /// 用户可以实现自已的映射器,来实现业务中数据与TEntity类之间的转换 /// 默认的映射器为 DataReaderEntityMapper ,SqlRepoEx中还实现了 /// 与Dapper互动的DapperEntityMapper。 /// IEntityMapper必需实现并指定,以供 SqlRepoEx 使用。 /// </summary> public interface IEntityMapper { IEnumerable<TEntity> Map<TEntity>(IDataReader reader) where TEntity : class, new(); List<TEntity> MapList<TEntity>(IDataReader reader) where TEntity : class, new(); TLEntity MapEntityList<TLEntity, T>(IDataReader reader) where TLEntity : List<T>, new() where T : class, new(); }
SqlRepoEx.Adapter.Dapper中的实现
/// <summary> /// 支持 Dapper 的实例映射器 /// https://github.com/StackExchange/Dapper /// </summary> public class DapperEntityMapper : IEntityMapper { /// <summary> /// 从访问关系数据库的数据提供者IDataReader。读取一个或多个正向的结果集流,并将此 /// 数据集映射到DTO列表中。 /// </summary> /// <typeparam name="TEntity">DTO 类型</typeparam> /// <param name="reader">访问关系数据库的数据提供者</param> /// <returns></returns> public IEnumerable<TEntity> Map<TEntity>(IDataReader reader) where TEntity : class, new() { return reader.Parse<TEntity>().ToList(); } /// <summary> /// 从访问关系数据库的数据提供者IDataReader。读取一个或多个正向的结果集流,并将此 /// 数据集映射到DTO列表中。 /// </summary> /// <typeparam name="TLEntity">List DTO 类型</typeparam> /// <typeparam name="T">DTO 类型</typeparam> /// <param name="reader">访问关系数据库的数据提供者</param> /// <returns></returns> public TLEntity MapEntityList<TLEntity, T>(IDataReader reader) where TLEntity : List<T>, new() where T : class, new() { var list = new TLEntity(); list.AddRange(reader.Parse<T>()); return list; } /// <summary> /// 从访问关系数据库的数据提供者IDataReader。读取一个或多个正向的结果集流,并将此 /// 数据集映射到DTO列表中。 /// </summary> /// <typeparam name="TEntity">DTO 类型</typeparam> /// <param name="reader">访问关系数据库的数据提供者</param> /// <returns></returns> public List<TEntity> MapList<TEntity>(IDataReader reader) where TEntity : class, new() { return reader.Parse<TEntity>().ToList(); } }
二、IStatementExecutor 语句执行器接口,其功能是 SqlRepoEx 执行Sql的各种操作
其接口定义为
/// <summary> /// SQL语句执行器(必需)。SqlRepoEx需要此接口的实现类来执行Sql语句。 /// 用户可自定义此接口实现类,以达到所需执行效果。 /// </summary> public interface IStatementExecutor { int ExecuteNonQuery(string sql); Task<int> ExecuteNonQueryAsync(string sql); int ExecuteNonQueryStoredProcedure(string name, params ParameterDefinition[] parameterDefinitions); Task<int> ExecuteNonQueryStoredProcedureAsync(string name, params ParameterDefinition[] parameterDefinitions); IDataReader ExecuteReader(string sql); Task<IDataReader> ExecuteReaderAsync(string sql); IDataReader ExecuteStoredProcedure(string name, params ParameterDefinition[] parametersDefinitions); Task<IDataReader> ExecuteStoredProcedureAsync(string name, params ParameterDefinition[] parametersDefinitions); IStatementExecutor UseConnectionProvider(IConnectionProvider connectionProvider); }
SqlRepoEx.Adapter.Dapper中的实现
/// <summary> /// Dapper语句执行器 /// https://github.com/StackExchange/Dapper /// </summary> public class DapperStatementExecutor : IStatementExecutor { private IConnectionProvider connectionProvider; private DbConnection dbConnection; private DynamicParameters TurnParameters(ParameterDefinition[] parameterDefinitions) { if (parameterDefinitions == null) { return null; } if (parameterDefinitions.Length == 0) { return null; } var p = new DynamicParameters(); foreach (var pd in parameterDefinitions) { p.Add(pd.Name, pd.Value, pd.DbType, pd.Direction, pd.Size); } return p; } /// <summary> /// Dapper语句执行器构造 /// </summary> /// <param name="connectionProvider">数据连接提供者</param> public DapperStatementExecutor(IConnectionProvider connectionProvider) { this.connectionProvider = connectionProvider; this.dbConnection = connectionProvider.GetDbConnection; } /// <summary> /// 执行并返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="sql">需要执行的sql</param> /// <returns></returns> public int ExecuteNonQuery(string sql) { return dbConnection.Execute(sql); } /// <summary> /// 异步执行并返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="sql">需要执行的sql</param> /// <returns></returns> public Task<int> ExecuteNonQueryAsync(string sql) { return dbConnection.ExecuteAsync(sql); } /// <summary> /// 执行指定存储过程,并返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="name">存储过程名</param> /// <param name="parameterDefinitions">存储过程参数列表</param> /// <returns>返回 ParameterDirection.ReturnValue 中的值</returns> public int ExecuteNonQueryStoredProcedure(string name, params ParameterDefinition[] parameterDefinitions) { var args = TurnParameters(parameterDefinitions); return dbConnection.Execute(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 异步执行指定存储过程,并返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="name">存储过程名</param> /// <param name="parameterDefinitions">存储过程参数列表</param> /// <returns>返回 ParameterDirection.ReturnValue 中的值</returns> public Task<int> ExecuteNonQueryStoredProcedureAsync(string name, params ParameterDefinition[] parameterDefinitions) { var args = TurnParameters(parameterDefinitions); return dbConnection.ExecuteAsync(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 执行指定sql,并以IDataReader形式返回。 /// </summary> /// <param name="sql">需要执行的sql</param> /// <returns></returns> public IDataReader ExecuteReader(string sql) { return dbConnection.ExecuteReader(sql); } /// <summary> /// 异步执行指定sql,并以IDataReader形式返回。 /// </summary> /// <param name="sql">需要执行的sql</param> /// <returns></returns> public Task<IDataReader> ExecuteReaderAsync(string sql) { return dbConnection.ExecuteReaderAsync(sql); } /// <summary> /// 执行指定存储过程,并以IDataReader形式返回。 /// </summary> /// <param name="name">存储过程名</param> /// <param name="parametersDefinitions">参数列表</param> /// <returns></returns> public IDataReader ExecuteStoredProcedure(string name, params ParameterDefinition[] parametersDefinitions) { var args = TurnParameters(parametersDefinitions); return dbConnection.ExecuteReader(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 异步执行指定存储过程,并以IDataReader形式返回。 /// </summary> /// <param name="name">存储过程名</param> /// <param name="parametersDefinitions">参数列表</param> /// <returns></returns> public Task<IDataReader> ExecuteStoredProcedureAsync(string name, params ParameterDefinition[] parametersDefinitions) { var args = TurnParameters(parametersDefinitions); return dbConnection.ExecuteReaderAsync(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 指定数据连接提供者 /// </summary> /// <param name="connectionProvider">数据连接提供者</param> /// <returns></returns> public IStatementExecutor UseConnectionProvider(IConnectionProvider connectionProvider) { this.connectionProvider = connectionProvider; return this; } }
也可发邮件至:azthinker@sina.com
GitHub的https://github.com/azthinker
开源中国 https://gitee.com/azthinker