1. 程式人生 > >輕量ORM-SqlRepoEx (十一)擴充套件

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