/// <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); }
/// <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); })); }
/// <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()); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); })); }
/// <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)); }
/// <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()); } }
/// <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)); }
/// <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); }