輕量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;
}
}