Beispiel #1
0
        /// <summary>
        /// 지정한 문화권의 모든 리소스 정보를 Hashtable로 반환한다.
        /// </summary>
        public Hashtable GetResources(CultureInfo culture)
        {
            if (IsDebugEnabled)
            {
                log.Debug("Get resources map... resourceType=[{0}], culture=[{1}]", ResourceName, culture);
            }

            var resourceMap = new Hashtable();

            try {
                culture = culture.GetOrCurrentCulture();

                using (var cmd = GetResourcesCommand(culture.Name))
                    using (var reader = Ado.ExecuteReader(cmd)) {
                        while (reader.Read())
                        {
                            var key   = reader.AsString("ResourceKey");
                            var value = reader.AsString("ResourceValue");

                            resourceMap.Add(key, value);
                        }
                    }
            }
            catch (Exception ex) {
                if (log.IsErrorEnabled)
                {
                    log.Error("리소스를 얻는데 실패했습니다. culture=[{0}]", culture);
                    log.Error(ex);
                }

                throw;
            }
            return(resourceMap);
        }
        /// <summary>
        /// <see cref="ExecuteInstance{T}(IAdoRepository,INameMapper,System.Data.Common.DbCommand,IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// DataReader로부터 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="nameMapper">DataReader 컬럼과 엔티티의 속성명의 Name 매퍼</param>
        /// <param name="targetFactory">대상 객체 생성 함수</param>
        /// <param name="firstResult">첫번째 레코드 인덱스 (0부터 시작)</param>
        /// <param name="maxResults">최대 레코드 갯수(0이면 끝까지)</param>
        /// <param name="additionalMapping">추가적인 매핑 함수</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IList <T> > ExecuteInstanceAsParallelAsync <T>(this IAdoRepository repository,
                                                                           INameMapper nameMapper,
                                                                           Func <T> targetFactory,
                                                                           int firstResult,
                                                                           int maxResults,
                                                                           Action <AdoResultRow, T> additionalMapping,
                                                                           string query,
                                                                           params IAdoParameter[] parameters)
        {
            nameMapper.ShouldNotBeNull("nameMapper");
            targetFactory.ShouldNotBeNull("targetFactory");
            query.ShouldNotBeWhiteSpace("query");

            if (IsDebugEnabled)
            {
                log.Debug("비동기적으로 ExecuteReader()을 수행하고, 병렬로 매핑하여 결과를 IList<{0}>으로 매핑합니다... " +
                          "query=[{1}], firstResult=[{2}], maxResults=[{3}]", typeof(T).Name, query, firstResult, maxResults);
            }

            return
                (Task.Factory
                 .StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapAsParallel <T>(targetFactory, nameMapper, firstResult, maxResults,
                                                    additionalMapping);
            }));
        }
        /// <summary>
        /// 비동기적으로 ExecuteReader()을 수행하고, 병렬 방식으로 매핑하여 결과를 IPageList{T} 으로 반환하는 Task를 빌드합니다
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="rowMapFunc">DataReader로부터 {T} 수형의 인스턴스로 변환하는 메소드</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="pageIndex">결과셋의 Page Index (0부터 시작)</param>
        /// <param name="pageSize">결과셋 Paging 시의 Page Size</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IPagingList <T> > ExecuteInstanceAsParallelAsync <T>(this IAdoRepository repository,
                                                                                 Func <AdoResultRow, T> rowMapFunc,
                                                                                 string query,
                                                                                 int pageIndex,
                                                                                 int pageSize,
                                                                                 params IAdoParameter[] parameters)
        {
            rowMapFunc.ShouldNotBeNull("converter");
            query.ShouldNotBeWhiteSpace("query");

            if (IsDebugEnabled)
            {
                log.Debug("비동기적으로 ExecuteReader()을 수행하고, 병렬 방식으로 매핑하여 결과를 IPageList<{0}>으로 반환하는 Task를 빌드합니다... " +
                          @"query=[{1}]", typeof(T).Name, query);
            }

            var itemsTask = Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return(reader.MapAsParallel <T>(rowMapFunc, pageIndex * pageSize, pageSize));
            });

            var totalItemCountTask = repository.CountAsync(query, parameters);

            var result = new PagingList <T>(itemsTask.Result, pageIndex, pageSize, totalItemCountTask.Result);

            return(Task.Factory.FromResult((IPagingList <T>)result));
        }
        /// <summary>
        /// Command를 수행하고, 결과를 XML 문자열로 반환합니다.
        /// </summary>
        /// <param name="repository">Repository</param>
        /// <param name="requestItem">요청 정보</param>
        /// <returns>Data 처리 결과의 XML 문자열</returns>
        public override string Execute(IAdoRepository repository, RequestItem requestItem) {
            Repository = repository;

            var method = requestItem.Method;
            var requestParameters = requestItem.Parameters;

            if(IsDebugEnabled)
                log.Debug("{0}를 수행합니다. method=[{1}], parameters=[{2}]",
                          GetType().FullName, method, requestParameters.CollectionToString());


            var query = repository.QueryProvider.GetQuery(method).AsText(method);
            string result;

            using(var cmd = repository.GetCommand(query, GetParameters(requestParameters))) {
                var reader = repository.ExecuteReader(cmd);
                var records = BuildResponse(reader);
                result = JsonTool.SerializeAsText(records);
            }

            if(IsDebugEnabled)
                log.Debug("{0}를 완료했습니다. method=[{1}], requestParameters=[{2}]", GetType().FullName, method,
                          requestParameters.CollectionToString());

            return result;
        }
        /// <summary>
        /// Command를 수행하고, 결과를 XML 문자열로 반환합니다.
        /// </summary>
        /// <param name="repository">Repository</param>
        /// <param name="requestItem">요청 정보</param>
        /// <returns>Data 처리 결과의 XML 문자열</returns>
        public override string Execute(IAdoRepository repository, RequestItem requestItem)
        {
            Repository = repository;

            var method            = requestItem.Method;
            var requestParameters = requestItem.Parameters;

            if (IsDebugEnabled)
            {
                log.Debug("{0}를 수행합니다. method=[{1}], parameters=[{2}]",
                          GetType().FullName, method, requestParameters.CollectionToString());
            }


            var    query = repository.QueryProvider.GetQuery(method).AsText(method);
            string result;

            using (var cmd = repository.GetCommand(query, GetParameters(requestParameters))) {
                var reader  = repository.ExecuteReader(cmd);
                var records = BuildResponse(reader);
                result = JsonTool.SerializeAsText(records);
            }

            if (IsDebugEnabled)
            {
                log.Debug("{0}를 완료했습니다. method=[{1}], requestParameters=[{2}]", GetType().FullName, method,
                          requestParameters.CollectionToString());
            }

            return(result);
        }
Beispiel #6
0
        //! ===============================================================================================

        /// <summary>
        /// 지정한 Command의 실행 결과 셋이 존재하는지 검사한다 (결과 셋의 레코드가 하나 이상이다)
        /// </summary>
        public static bool Exists(this IAdoRepository repository, DbCommand cmd, params IAdoParameter[] parameters)
        {
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("결과 셋이 존재하는지 검사합니다... commandText=[{0}], parameters=[{1}]", cmd.CommandText, parameters.CollectionToString());
            }

            using (var dr = repository.ExecuteReader(cmd, parameters))
                return(dr.Read());
        }
Beispiel #7
0
        //! ===============================================================================================

        /// <summary>
        /// 지정된 Command를 실행한 결과 셋의 레코드 갯수를 구한다.
        /// </summary>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="cmd">실행할 Command 객체</param>
        /// <param name="parameters">Command 인자 정보</param>
        /// <returns>결과 셋의 레코드 수</returns>
        /// <remarks>
        /// 실제 SQL의 count(*) 함수를 생성하는 것이 아니라, IDataReader를 이용하여 결과 셋을 가져와서 갯수만 센다.
        /// 장점은 DataSet을 이용하여 Paging하는 것보다 빠르고, Count 용 Query문을 따로 만들 필요가 없다.
        /// 단점은 SQL의 count(*) 함수보다는 당연히 느리다.
        /// </remarks>
        public static int Count(this IAdoRepository repository, DbCommand cmd, params IAdoParameter[] parameters)
        {
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("결과 셋의 갯수를 계산합니다. commandText=[{0}], parameters=[{1}]", cmd.CommandText, parameters.CollectionToString());
            }

            using (var dr = repository.ExecuteReader(cmd, parameters)) {
                return(dr.Count());
            }
        }
Beispiel #8
0
        //! ======================================================================================

        /// <summary>
        /// 비동기 방식으로 작업을 <paramref name="query"/>를 수행하여, <see cref="IDataReader"/>를 결과값으로 제공하는 Task를 반환합니다.
        /// </summary>
        /// <param name="repository">Repository</param>
        /// <param name="query">실행할 쿼리문 또는 Procedure Name</param>
        /// <param name="parameters">Parameters</param>
        /// <returns>결과셋을 IDataReader 로 결과를 제공하는 Task</returns>
        public static Task <IDataReader> ExecuteReaderAsync(this IAdoRepository repository, string query,
                                                            params IAdoParameter[] parameters)
        {
            query.ShouldNotBeWhiteSpace("query");

            if (IsDebugEnabled)
            {
                log.Debug("비동기 방식으로 쿼리를 수행하여 IDataReader를 얻습니다... query=[{0}], parameters=[{1}]",
                          query, parameters.CollectionToString());
            }

            return(Task.Factory.StartNew(() => repository.ExecuteReader(query, parameters)));
        }
        /// <summary>
        /// <see cref="IAdoRepository.ExecuteInstance{T}(System.Func{System.Data.IDataReader,T},System.Data.Common.DbCommand,NFramework.Data.IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// DataReader로부터 <paramref name="filter"/> 에 만족하는 레코드만 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="persister">대상 객체를 빌드하는 Persister</param>
        /// <param name="filter">매핑할 Row를 선별할 필터 함수</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IEnumerable <T> > ExecuteInstanceIfAsync <T>(this IAdoRepository repository,
                                                                         IReaderPersister <T> persister,
                                                                         Func <IDataReader, bool> filter,
                                                                         string query,
                                                                         params IAdoParameter[] parameters) where T : class
        {
            persister.ShouldNotBeNull("persister");
            filter.ShouldNotBeNull("filter");

            return(Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapIf <T>(persister, filter, null);
            }));
        }
Beispiel #10
0
        /// <summary>
        /// <see cref="IAdoRepository.ExecuteInstance{T}(System.Func{System.Data.IDataReader,T},System.Data.Common.DbCommand,NFramework.Data.IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// <paramref name="continuationCondition"/> 조건이 만족할 동안만, DataReader로부터 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="mapFunc">매핑 함수</param>
        /// <param name="continuationCondition">매핑을 계속할 조건인지 판단하는 델리게이트</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IEnumerable <T> > ExecuteInstanceWhileAsync <T>(this IAdoRepository repository,
                                                                            Func <IDataReader, T> mapFunc,
                                                                            Func <IDataReader, bool> continuationCondition,
                                                                            string query,
                                                                            params IAdoParameter[] parameters) where T : class
        {
            mapFunc.ShouldNotBeNull("mapFunc");
            continuationCondition.ShouldNotBeNull("continuationCondition");

            return(Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapWhile <T>(mapFunc, continuationCondition);
            }));
        }
        /// <summary>
        /// <see cref="IAdoRepository.ExecuteInstance{T}(System.Func{System.Data.IDataReader,T},System.Data.Common.DbCommand,NFramework.Data.IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// DataReader로부터 <paramref name="filter"/> 에 만족하는 레코드만 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="mapFunc">매핑 함수</param>
        /// <param name="filter">매핑할 Row를 선별할 필터 함수</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IEnumerable <T> > ExecutInstanceIfTask <T>(this IAdoRepository repository,
                                                                       Func <IDataReader, T> mapFunc,
                                                                       Func <IDataReader, bool> filter,
                                                                       string query,
                                                                       params IAdoParameter[] parameters) where T : class
        {
            mapFunc.ShouldNotBeNull("mapFunc");
            filter.ShouldNotBeNull("filter");

            return(Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapIf <T>(mapFunc, filter);
            }));
        }
Beispiel #12
0
        /// <summary>
        /// <see cref="IAdoRepository.ExecuteInstance{T}(System.Func{System.Data.IDataReader,T},System.Data.Common.DbCommand,NFramework.Data.IAdoParameter[])"/> 를 비동기적으로 수행하여,
        /// <paramref name="continuationCondition"/> 조건이 만족할 동안만, DataReader로부터 T 수형의 인스턴스를 매핑한다.
        /// </summary>
        /// <typeparam name="T">결과 셋으로 표현할 엔티티의 수형</typeparam>
        /// <param name="repository"><see cref="IAdoRepository"/></param>
        /// <param name="targetFactory">대상 객체 생성용 Factory</param>
        /// <param name="nameMap">DB 컬럼명- 클래스 속성명 매핑 정보</param>
        /// <param name="continuationCondition">매핑을 계속할 조건인지 판단하는 델리게이트</param>
        /// <param name="query">실행할 SQL문 또는 Procedure Name</param>
        /// <param name="parameters">패러미터</param>
        /// <returns>매핑한 엔티티 컬렉션을 결과값으로 가지는 Task</returns>
        public static Task <IEnumerable <T> > ExecuteInstanceWhileAsync <T>(this IAdoRepository repository,
                                                                            Func <T> targetFactory,
                                                                            INameMap nameMap,
                                                                            Func <IDataReader, bool> continuationCondition,
                                                                            string query,
                                                                            params IAdoParameter[] parameters) where T : class
        {
            nameMap.ShouldNotBeNull("nameMap");
            continuationCondition.ShouldNotBeNull("continuationCondition");

            return(Task.Factory.StartNew(() => {
                using (var reader = repository.ExecuteReader(query, parameters))
                    return reader.MapWhile <T>(ActivatorTool.CreateInstance <T>,
                                               nameMap,
                                               continuationCondition,
                                               null);
            }));
        }
Beispiel #13
0
        /// <summary>
        /// Execute DbCommand, Build instance of specified type by mapping DataReader Column Value to Instance Property Value
        /// </summary>
        /// <typeparam name="T">Type of Persistent object</typeparam>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="nameMap">Key = ColumnName of DataReader, Value = Property Name of Specifieid Type</param>
        /// <param name="cmd">Instance of DbCommand to executed</param>
        /// <param name="parameters">Command parameters</param>
        /// <returns>Collection of Persistent object</returns>
        public static IList <T> ExecuteInstance <T>(this IAdoRepository repository,
                                                    INameMap nameMap,
                                                    DbCommand cmd,
                                                    params IAdoParameter[] parameters) where T : class
        {
            nameMap.ShouldNotBeNull("nameMap");
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("DataReader를 INameMap를 통해 지정된 Class의 인스턴스들을 생성합니다. " +
                          "persistent=[{0}], nameMap=[{1}], commandText=[{2}], parameters=[{3}]",
                          typeof(T).FullName, nameMap.DictionaryToString(), cmd.CommandText, parameters.CollectionToString());
            }

            using (var reader = repository.ExecuteReader(cmd, parameters))
                return(reader.Map <T>(ActivatorTool.CreateInstance <T>, nameMap));
        }
Beispiel #14
0
        /// <summary>
        /// DbCommand를 실행해 얻은 DataReader를 Converter를 통해 지정된 형식의 인스턴스를 만든다.
        /// </summary>
        /// <typeparam name="T">Type of persistent object</typeparam>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="mapFunc">IDataReader의 한 레코드인 IDataRecord 정보를 가지고, Persistent Object를 만들 Converter</param>
        /// <param name="cmd">Instance of DbCommand to executed</param>
        /// <param name="parameters">Parameters for DbCommand to execute</param>
        /// <returns>Collection of Persistent Object</returns>
        public static IList <T> ExecuteInstance <T>(this IAdoRepository repository,
                                                    Func <IDataReader, T> mapFunc,
                                                    DbCommand cmd,
                                                    params IAdoParameter[] parameters)
        {
            mapFunc.ShouldNotBeNull("mapFunc");
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("DataReader를 Mapping function 를 통해 지정된 Class의 인스턴스들을 생성합니다. " +
                          "persistent=[{0}], mapFunc=[{1}], commandText=[{2}], parameters=[{3}]",
                          typeof(T).FullName, mapFunc, cmd.CommandText, parameters.CollectionToString());
            }

            using (var reader = repository.ExecuteReader(cmd, parameters))
                return(reader.Map <T>(mapFunc));
        }
Beispiel #15
0
        /// <summary>
        /// Execute DbCommand, Build instance of specified type from IDataReader using Persister
        /// </summary>
        /// <typeparam name="T">Type of persistent object</typeparam>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="persister">Persister from IDataReader</param>
        /// <param name="cmd">Instance of DbCommand</param>
        /// <param name="parameters">Parameters for DbCommand to execute</param>
        /// <returns>List of Persistent Object</returns>
        public static IList <T> ExecuteInstance <T>(this IAdoRepository repository,
                                                    IReaderPersister <T> persister,
                                                    DbCommand cmd,
                                                    params IAdoParameter[] parameters) where T : class
        {
            persister.ShouldNotBeNull("persister");
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("DataReader를 IReaderPersister를 통해 지정된 Class의 인스턴스들을 생성합니다. " +
                          "persistent=[{0}], persister=[{1}], commandText=[{2}], parameters=[{3}]",
                          typeof(T).FullName, persister, cmd.CommandText, parameters.CollectionToString());
            }

            using (var reader = repository.ExecuteReader(cmd, parameters))
                return(reader.Map <T>(persister));
        }
Beispiel #16
0
        /// <summary>
        /// 지정된 Command를 실행하여, 결과 셋을 Paging하여, 지정된 Page에 해당하는 정보만 Persistent Object로 빌드하여 반환한다.
        /// </summary>
        /// <typeparam name="T">Persistent Object의 수형</typeparam>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="mapFunc">IDataReader로부터 Persistent Object를 빌드하는 Mapping function</param>
        /// <param name="cmd">실행할 DbCommand</param>
        /// <param name="pageIndex">결과셋의 Page Index (0부터 시작)</param>
        /// <param name="pageSize">결과셋 Paging 시의 Page Size</param>
        /// <param name="parameters">DbCommand 실행시의 Parameter 정보</param>
        /// <returns>Paging된 Persistent Object의 List</returns>
        public static IPagingList <T> ExecuteInstance <T>(this IAdoRepository repository,
                                                          Func <IDataReader, T> @mapFunc,
                                                          DbCommand cmd,
                                                          int pageIndex,
                                                          int pageSize,
                                                          params IAdoParameter[] parameters)
        {
            @mapFunc.ShouldNotBeNull("@mapFunc");
            cmd.ShouldNotBeNull("cmd");

            pageIndex.ShouldBePositiveOrZero("pageIndex");
            pageSize.ShouldBePositive("pageSize");

            if (IsDebugEnabled)
            {
                log.Debug("ExecuteReader를 수행해 엔티티로 매핑합니다... " +
                          "CommandText=[{0}], @mapFunc=[{1}], pageIndex=[{2}], pageSize=[{3}], parameters=[{4}]",
                          cmd.CommandText, @mapFunc, pageIndex, pageSize, parameters.CollectionToString());
            }


            var query       = cmd.CommandText;
            var firstResult = pageIndex * pageSize;
            var maxResults  = pageSize;

            var totalItemCountTask = repository.CountAsync(query, parameters);

            IList <T> instances;

            using (var dr = repository.ExecuteReader(cmd, parameters))
                instances = dr.Map <T>(@mapFunc, firstResult, maxResults);

            var pagingList = new PagingList <T>(instances, pageIndex, pageSize, totalItemCountTask.Result);

            if (IsDebugEnabled)
            {
                log.Debug("ExecuteReader를 수행해 엔티티로 매핑했습니다!!! pageIndex=[{0}], pageSize=[{1}], totalItemCount=[{2}]",
                          pageIndex, pageSize, totalItemCountTask.Result);
            }

            return(pagingList);
        }
Beispiel #17
0
        /// <summary>
        /// 지정된 Command를 실행하여, 결과 셋을 Paging하여, 지정된 Page에 해당하는 정보만 Persistent Object로 빌드하여 반환한다.
        /// </summary>
        /// <typeparam name="T">Persistent Object의 수형</typeparam>
        /// <param name="repository">IAdoRepository 인스턴스</param>
        /// <param name="nameMap">컬럼명:속성명의 매핑정보</param>
        /// <param name="additionalMapping">추가적인 매핑 함수</param>
        /// <param name="cmd">실행할 DbCommand</param>
        /// <param name="pageIndex">결과셋의 Page Index (0부터 시작)</param>
        /// <param name="pageSize">결과셋 Paging 시의 Page Size</param>
        /// <param name="parameters">DbCommand 실행시의 Parameter 정보</param>
        /// <returns>Paging된 Persistent Object의 List</returns>
        public static IPagingList <T> ExecuteInstance <T>(this IAdoRepository repository,
                                                          INameMap nameMap,
                                                          Action <IDataReader, T> additionalMapping,
                                                          DbCommand cmd,
                                                          int pageIndex,
                                                          int pageSize,
                                                          params IAdoParameter[] parameters) where T : class
        {
            nameMap.ShouldNotBeNull("nameMap");
            cmd.ShouldNotBeNull("cmd");

            if (IsDebugEnabled)
            {
                log.Debug("ExecuteReader를 수행해 PersistentObject로 매핑합니다... " +
                          "CommandText=[{0}], NameMapping=[{1}], pageIndex=[{2}], pageSize=[{3}], parameters=[{4}]",
                          cmd.CommandText, nameMap, pageIndex, pageSize, parameters.CollectionToString());
            }


            var query       = cmd.CommandText;
            var firstResult = pageIndex * pageSize;
            var maxResults  = pageSize;

            var totalItemCountTask = repository.CountAsync(query, parameters);

            IList <T> instances;

            using (var dr = repository.ExecuteReader(cmd, parameters))
                instances = dr.Map <T>(ActivatorTool.CreateInstance <T>, nameMap, firstResult, maxResults, additionalMapping);


            var pagingList = new PagingList <T>(instances, pageIndex, pageSize, totalItemCountTask.Result);

            if (IsDebugEnabled)
            {
                log.Debug("ExecuteReader를 수행해 PersistentObject로 매핑했습니다!!! pageIndex=[{0}], pageSize=[{1}], totalItemCount=[{2}]",
                          pageIndex, pageSize, totalItemCountTask.Result);
            }

            return(pagingList);
        }