Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 查询并根据结果返回目标类型的实例序列。
        /// </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>
        public static IEnumerable <T> Query <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);
            var mapper    = (IMapper <T>)cache?.Mapper;

            if (cache == null)
            {
                cache = CreateCacheItem(sql, commandType, param);
            }

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

            return(rows.Select((row, idx) =>
            {
                // mapper没有缓存时,在第一行上创建mapper并加入缓存。
                if (mapper == null)
                {
                    mapper = MapperParser.Parse <T>(row);
                    cache.Mapper = mapper;
                    CommandCache.Set(id, cache);
                }

                return mapper.MapRow(row, idx + 1);
            }));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 查询并根据结果返回目标类型的实例序列。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">参数表。</param>
        /// <returns>目标类型的实例序列。</returns>
        public static IEnumerable <T> IxQuery <T>(this IDbClient client, string sql, params object[] param)
        {
            var identity = new CommandIdentity(client.ConnectionString, string.Empty, null, null, typeof(T));
            var cache    = CommandCache.Get(identity);

            var mapper = cache == null ? null : (IMapper <T>)cache.Mapper;
            var rowNum = 0;

            // 展开foreach循环,使mapper == null的仅判断一次
            using (var iter = IxRows(client, sql, param).GetEnumerator())
            {
                if (!iter.MoveNext())
                {
                    yield break;
                }

                if (mapper == null)
                {
                    mapper = MapperParser.Parse <T>(iter.Current);
                    CommandCache.Set(identity, new CommandCacheItem {
                        Mapper = mapper
                    });
                }

                do
                {
                    yield return(mapper.MapRow(iter.Current, ++rowNum));
                } while (iter.MoveNext());
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 查询并根据结果创建目标类型的实例。
        /// 若满足条件的记录不存在,返回目标类型的默认值(对于引用类型为<c>null</c>)。
        /// </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>
        public static T Get <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.Get((IMapper <T>)cache.Mapper, cache.Sql,
                                  cache.Params(client, param), commandType, timeout));
            }

            cache = CreateCacheItem(sql, commandType, param);

            var row = client.GetRow(sql, cache.Params(client, param), commandType, timeout);

            if (row == null)
            {
                return(default(T));
            }

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

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

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

            return(res);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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 == null ? null : 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);
            var rowCount = 0;
            var res      = default(T);

            using (var iter = rows.GetEnumerator())
            {
                if (iter.MoveNext())
                {
                    var mapper = MapperParser.Parse <T>(iter.Current);
                    cache.Mapper = mapper;
                    CommandCache.Set(id, cache);
                    res = mapper.MapRow(iter.Current, 1);
                    rowCount++;
                }

                while (iter.MoveNext())
                {
                    rowCount++;
                }
            }

            if (rowCount == 1)
            {
                return(res);
            }

            throw new IncorrectResultSizeException(sql, CommandType.Text, dbParam, 1, rowCount);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 查询并根据结果返回目标类型的实例序列。
        /// 这是一个异步操作。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">参数表。</param>
        /// <returns>目标类型的实例序列。</returns>
        public static async Task <IEnumerable <T> > IxQueryAsync <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);
            var mapper   = (IMapper <T>)cache?.Mapper;

            var rows = await IxRowsAsync(client, sql, param);

            return(rows.Select((row, idx) =>
            {
                // mapper没有缓存时,在第一行上创建mapper并加入缓存。
                if (mapper == null)
                {
                    mapper = MapperParser.Parse <T>(row);
                    CommandCache.Set(identity, new CommandCacheItem {
                        Mapper = mapper
                    });
                }

                return mapper.MapRow(row, idx + 1);
            }));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 查询并根据结果创建目标类型的实例。
        /// 若满足条件的记录不存在,返回目标类型的默认值(对于引用类型为<c>null</c>)。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">参数表。</param>
        /// <returns>目标类型的实例。</returns>
        public static T IxGet <T>(this IDbClient client, string sql, params object[] param)
        {
            var identity = new CommandIdentity(client.ConnectionString, string.Empty, null, null, typeof(T));
            var cache    = CommandCache.Get(identity);

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

            var rows = IxRows(client, sql, param);

            foreach (var row in rows)
            {
                var mapper = MapperParser.Parse <T>(row);
                CommandCache.Set(identity, new CommandCacheItem {
                    Mapper = mapper
                });
                return(mapper.MapRow(row, 1));
            }

            return(default(T));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 查询并根据结果返回目标类型的实例序列。
        /// </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>
        public static IEnumerable <T> Query <T>(this IDbClient client,
                                                string sql, object param = null, CommandType commandType = CommandType.Text, int timeout = 0)
        {
            var paramType = param == null ? null : param.GetType();
            var id        = new CommandIdentity(client.ConnectionString, sql, commandType, paramType, typeof(T));
            var cache     = CommandCache.Get(id);
            var mapper    = cache == null ? null : (IMapper <T>)cache.Mapper;
            var rowNum    = 0;

            if (cache == null)
            {
                cache = CreateCacheItem(sql, commandType, param);
            }

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

            // 展开foreach循环,使mapper == null的仅判断一次
            using (var iter = rows.GetEnumerator())
            {
                if (!iter.MoveNext())
                {
                    yield break;
                }

                if (mapper == null)
                {
                    mapper       = MapperParser.Parse <T>(iter.Current);
                    cache.Mapper = mapper;
                    CommandCache.Set(id, cache);
                }

                do
                {
                    yield return(mapper.MapRow(iter.Current, ++rowNum));
                } while (iter.MoveNext());
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 查询并根据结果创建目标类型的实例。
        /// 若满足条件的记录不存在,返回目标类型的默认值(对于引用类型为<c>null</c>)。
        /// 这是一个异步操作。
        /// </summary>
        /// <typeparam name="T">查询的目标类型。</typeparam>
        /// <param name="client"><see cref="IDbClient"/>的实例。</param>
        /// <param name="sql">SQL语句。</param>
        /// <param name="param">参数表。</param>
        /// <returns>目标类型的实例。</returns>
        public static async Task <T> IxGetAsync <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 IxGetAsync(client, (IMapper <T>) cache.Mapper, sql, param));
            }

            var row = await IxGetRowAsync(client, sql, param);

            if (row == null)
            {
                return(default(T));
            }

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

            CommandCache.Set(identity, new CommandCacheItem {
                Mapper = mapper
            });
            return(mapper.MapRow(row, 1));
        }
Ejemplo n.º 11
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 T IxForceGet <T>(this IDbClient client, string sql, params object[] param)
        {
            var identity = new CommandIdentity(client.ConnectionString, string.Empty, null, null, typeof(T));
            var cache    = CommandCache.Get(identity);

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

            var dbParam  = GenerateParameters(client, param).ToList();
            var rows     = client.Rows(sql, dbParam);
            var rowCount = 0;
            var res      = default(T);

            foreach (var row in rows)
            {
                if (rowCount == 0)
                {
                    var mapper = MapperParser.Parse <T>(row);
                    CommandCache.Set(identity, new CommandCacheItem {
                        Mapper = mapper
                    });
                    res = mapper.MapRow(row, 1);
                }

                rowCount++;
            }

            if (rowCount == 1)
            {
                return(res);
            }

            throw new IncorrectResultSizeException(sql, CommandType.Text, dbParam, 1, rowCount);
        }