using (MySqlConnection conn = getConn(db)) { MySqlCommand cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { string id = reader.GetString("id"); string name = reader.GetString("name"); //。。 } reader.Close(); conn.Close(); } | using (OracleConnection conn = connectDB()) { OracleCommand cmd = new OracleCommand(sql, conn); OracleDataReader od = cmd.ExecuteReader(); //。。 } | 注意 xxConnection, 注意 xxCommand 注意 xxDataReader |
public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { CommandDefinition command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); IEnumerable enumerable = cnn.QueryImpl(command, typeof(T)); if (!command.Buffered) { return enumerable; } return enumerable.ToList(); } | 初始化配置,暂且无视 关键语句,进去看看 |
private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefinition command, Type effectiveType) { object parameters = command.Parameters; Identity identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, parameters?.GetType()); CacheInfo cacheInfo = GetCacheInfo(identity, parameters, command.AddToCache); IDbCommand cmd = null; IDataReader reader = null; bool wasClosed = cnn.State == ConnectionState.Closed; try { cmd = command.SetupCommand(cnn, cacheInfo.ParamReader); if (wasClosed) { cnn.Open(); } reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, CommandBehavior.SingleResult | CommandBehavior.SequentialAccess); wasClosed = false; DeserializerState deserializerState = cacheInfo.Deserializer; int columnHash = GetColumnHash(reader); if (deserializerState.Func != null && deserializerState.Hash == columnHash) { goto IL_016c; } if (reader.FieldCount != 0) { DeserializerState deserializerState3 = cacheInfo.Deserializer = new DeserializerState(columnHash, GetDeserializer(effectiveType, reader, 0, -1, returnNullIfFirstMissing: false)); deserializerState = deserializerState3; if (command.AddToCache) { SetQueryCache(identity, cacheInfo); } goto IL_016c; } goto end_IL_0098; IL_016c: Func func = deserializerState.Func; _ = (Nullable.GetUnderlyingType(effectiveType) ?? effectiveType); while (reader.Read()) { object val = func(reader); yield return GetValue(reader, effectiveType, val); } while (reader.NextResult()) { } reader.Dispose(); reader = null; command.OnCompleted(); end_IL_0098:; } finally { if (reader != null) { if (!reader.IsClosed) { try { cmd.Cancel(); } catch { } } reader.Dispose(); } if (wasClosed) { cnn.Close(); } cmd?.Parameters.Clear(); cmd?.Dispose(); } } | 已知, effectiveType就是typeof(T); 数据库访问里面,最需要关注的对象就是: DbConnection, DbCommand, DataReader reader的实现在这里; reader结果是有列的; 反编译出来的IL语言, 代码跳转到 IL_016c 处; IL_016c 在这里; val 是一行数据; 关键代码,进去看看 |
[MethodImpl(MethodImplOptions.AggressiveInlining)] private static T GetValue(IDataReader reader, Type effectiveType, object val) { if (val is T) { return (T)val; } if (val == null && (!effectiveType.IsValueType || Nullable.GetUnderlyingType(effectiveType) != null)) { return default(T); } Array array = val as Array; if (array != null && typeof(T).IsArray) { Type elementType = typeof(T).GetElementType(); Array array2 = Array.CreateInstance(elementType, array.Length); for (int i = 0; i < array.Length; i++) { array2.SetValue(Convert.ChangeType(array.GetValue(i), elementType, CultureInfo.InvariantCulture), i); } return (T)(object)array2; } try { Type conversionType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; return (T)Convert.ChangeType(val, conversionType, CultureInfo.InvariantCulture); } catch (Exception ex) { ThrowDataException(ex, 0, reader, val); return default(T); } } | 如果一行里面的数据类型就是T,代表就是一个列的值对象 如果一行数据里面有很多数据 |
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |