Beispiel #1
0
        /// <summary>
        /// 查询并根据结果创建目标类型的实例。
        /// SQL命中的记录必须为1行,否则抛出异常。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">记录SQL参数的对象。</param>
        /// <param name="commandType">命令的类型。</param>
        /// <param name="timeout">命令的超时时间,单位毫秒。0为不指定。</param>
        /// <returns>目标类型的实例。</returns>
        /// <exception cref="IncorrectResultSizeException">当SQL命中的记录行数不为 1。</exception>
        public static T ForceGet <T>(this IDbClient client,
                                     string sql, object param = null, CommandType commandType = CommandType.Text, int timeout = 0)
        {
            var paramType = param?.GetType();
            var id        = new CommandIdentity(client.ConnectionString, sql, commandType, paramType, typeof(T));
            var cache     = CommandCache.Get(id);

            if (cache != null)
            {
                return(client.ForceGet((IMapper <T>)cache.Mapper, cache.Sql,
                                       cache.Params(client, param), commandType, timeout));
            }

            cache = CreateCacheItem(sql, commandType, param);
            var dbParam = cache.Params(client, param);
            var rows    = client.Rows(sql, dbParam, commandType, timeout);

            IDataRecord row;
            int         rowCount;

            if (!DbClientHelper.TryReadUniqueRow(rows, out row, out rowCount))
            {
                throw new IncorrectResultSizeException(sql, CommandType.Text, dbParam, 1, rowCount);
            }

            var mapper = MapperParser.Parse <T>(row);

            cache.Mapper = mapper;
            CommandCache.Set(id, cache);

            var res = mapper.MapRow(row, 1);

            return(res);
        }
Beispiel #2
0
        /// <summary>
        /// 查询并根据结果创建目标类型的实例。
        /// SQL命中的记录必须为1行,否则抛出异常。
        /// 这是一个异步操作。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">参数表。</param>
        /// <returns>目标类型的实例。</returns>
        /// <exception cref="IncorrectResultSizeException">当SQL命中的记录行数不为 1。</exception>
        public static async Task <T> IxForceGetAsync <T>(this IDbClient client, string sql, params object[] param)
        {
            var identity = new CommandIdentity(client.ConnectionString, sql, null, null, typeof(T));
            var cache    = CommandCache.Get(identity);

            if (cache != null)
            {
                return(await IxForceGetAsync(client, (IMapper <T>) cache.Mapper, sql, param));
            }

            var dbParam = GenerateParameters(client, param).ToList();
            var rows    = await client.RowsAsync(sql, dbParam);

            IDataRecord row;
            int         rowCount;

            if (!DbClientHelper.TryReadUniqueRow(rows, out row, out rowCount))
            {
                throw new IncorrectResultSizeException(sql, CommandType.Text, dbParam, 1, rowCount);
            }

            var mapper = MapperParser.Parse <T>(row);

            CommandCache.Set(identity, new CommandCacheItem {
                Mapper = mapper
            });

            var res = mapper.MapRow(row, 1);

            return(res);
        }
Beispiel #3
0
        /// <summary>
        /// 使用<see cref="IMapper{T}"/>查询指定对象。
        /// SQL命中的记录必须为1行,否则抛出异常。
        /// 这是一个异步操作。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="mapper"><see cref="IMapper{T}"/>的实例。</param>
        /// <param name="sql">查询SQL。</param>
        /// <param name="parameters">参数序列。空序列或null表示没有参数。</param>
        /// <param name="commandType">命令的类型。</param>
        /// <param name="timeout">命令的超时时间,单位毫秒。0表示不指定,此时套用默认的超时设置。</param>
        /// <returns>目标类型的实例。</returns>
        /// <exception cref="IncorrectResultSizeException">当SQL命中的记录行数不为 1。</exception>
        public virtual async Task <T> ForceGetAsync <T>(IMapper <T> mapper,
                                                        string sql, IEnumerable <DbParameter> parameters = null,
                                                        CommandType commandType = CommandType.Text, int timeout = 0)
        {
            if (!AsyncEnabled)
            {
                return(ForceGet(mapper, sql, parameters, commandType, timeout));
            }

            DbConnection connection = null;
            IDataReader  reader     = null;
            DbCommand    cmd        = null;

            try
            {
                connection = await CreateAndOpenConnectionAsync();

                cmd    = CreateCommand(sql, connection, parameters, commandType, timeout);
                reader = await cmd.ExecuteReaderAsync();

                int rowCount;
                T   result;
                if (DbClientHelper.TryMapUniqueRow(reader, mapper, out result, out rowCount))
                {
                    return(result);
                }

                throw new IncorrectResultSizeException(sql, CommandType.Text, parameters, 1, rowCount);
            }
            catch (Exception ex)
            {
                throw new SqlExecutingException(sql, commandType, parameters, ex);
            }
            finally
            {
                cmd?.Parameters.Clear();

                if (reader != null && !reader.IsClosed)
                {
                    reader.Close();
                }

                if (connection != null)
                {
                    CloseConnection(connection);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// 使用<see cref="IMapper{T}"/>查询指定对象。
        /// SQL命中的记录必须为1行,否则抛出异常。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="mapper"><see cref="IMapper{T}"/>的实例。</param>
        /// <param name="sql">查询SQL。</param>
        /// <param name="parameters">参数序列。空序列或null表示没有参数。</param>
        /// <param name="commandType">命令的类型。</param>
        /// <param name="timeout">命令的超时时间,单位毫秒。0表示不指定,此时套用默认的超时设置。</param>
        /// <returns>目标类型的实例。</returns>
        /// <exception cref="IncorrectResultSizeException">当SQL命中的记录行数不为 1。</exception>
        public virtual T ForceGet <T>(IMapper <T> mapper,
                                      string sql, IEnumerable <DbParameter> parameters = null,
                                      CommandType commandType = CommandType.Text, int timeout = 0)
        {
            ArgAssert.NotNullOrEmpty(sql, nameof(sql));
            ArgAssert.NotNull(mapper, nameof(mapper));

            DbConnection connection = null;
            IDataReader  reader     = null;
            DbCommand    cmd        = null;

            try
            {
                connection = CreateAndOpenConnection();
                cmd        = CreateCommand(sql, connection, parameters, commandType, timeout);
                reader     = cmd.ExecuteReader();

                int rowCount;
                T   result;
                if (DbClientHelper.TryMapUniqueRow(reader, mapper, out result, out rowCount))
                {
                    return(result);
                }

                throw new IncorrectResultSizeException(sql, CommandType.Text, parameters, 1, rowCount);
            }
            catch (Exception ex)
            {
                throw new SqlExecutingException(sql, commandType, parameters, ex);
            }
            finally
            {
                cmd?.Parameters.Clear();

                if (reader != null && !reader.IsClosed)
                {
                    reader.Close();
                }

                if (connection != null)
                {
                    CloseConnection(connection);
                }
            }
        }