From 1b23a6210338afe5d50abde1d931784267d29867 Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Sat, 23 Apr 2011 22:09:29 +1000 Subject: [PATCH] code cleanup ... --- Dapper/SqlMapper.cs | 174 ++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 94 deletions(-) diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index 99070a8..86f85d4 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -17,8 +17,13 @@ namespace Dapper { public static class SqlMapper { - static ConcurrentDictionary cachedSerializers = new ConcurrentDictionary(); - static ConcurrentDictionary>> cachedParamReaders = new ConcurrentDictionary>>(); + class CacheInfo + { + public object Deserializer { get; set; } + public Func> ParamReader { get; set; } + } + + static ConcurrentDictionary queryCache = new ConcurrentDictionary(); static Dictionary typeMap; static SqlMapper() @@ -76,7 +81,7 @@ private static DbType LookupDbType(Type type) } } - throw new NotSupportedException("The type : " + type.ToString() + " is not supported by the mapper"); + throw new NotSupportedException("The type : " + type.ToString() + " is not supported by dapper"); } class ParamInfo @@ -101,17 +106,20 @@ private class Identity : IEquatable public String ConnectionString { get { return connectionString; } } public Type Type { get { return type; } } public string Sql { get { return sql; } } - internal Identity(string sql, IDbConnection cnn, Type type) + public Type ParametersType { get { return ParametersType; } } + internal Identity(string sql, IDbConnection cnn, Type type, Type parametersType) { this.sql = sql; this.connectionString = cnn.ConnectionString; this.type = type; + this.parametersType = parametersType; unchecked { hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode()); hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode()); hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionString.GetHashCode()); + hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode()); } } public override bool Equals(object obj) @@ -122,14 +130,19 @@ public override bool Equals(object obj) private readonly int hashCode; private readonly Type type; private readonly string connectionString; + private readonly Type parametersType; public override int GetHashCode() { return hashCode; } public bool Equals(Identity other) { - return other != null && this.type == other.type - && sql == other.sql && connectionString == other.connectionString; + return + other != null && + this.type == other.type && + sql == other.sql && + connectionString == other.connectionString && + parametersType == other.parametersType; } } @@ -139,7 +152,15 @@ public bool Equals(Identity other) /// Number of rows affected public static int Execute(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null) { - return ExecuteCommand(cnn, transaction, sql, GetParamInfo(param)); + var identity = new Identity(sql, cnn, null, param == null ? null : param.GetType()); + var info = GetCacheInfo(param, identity); + List paramInfos = null; + if (info.ParamReader != null) + { + paramInfos = info.ParamReader(param); + } + + return ExecuteCommand(cnn, transaction, sql, paramInfos); } /// @@ -147,49 +168,69 @@ public static int Execute(this IDbConnection cnn, string sql, object param = nul /// public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true) { - if (!buffered) - { - return EnumerateMapperQuery(cnn, sql, param, transaction); - } + return Query(cnn, sql, param, transaction, buffered); + } - var identity = new Identity(sql, cnn, DynamicStub.Type); - var list = new List(); - using (var reader = GetReader(cnn, transaction, sql, GetParamInfo(param))) + public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true) + { + var data = QueryInternal(cnn, sql, param, transaction); + if (buffered) { - Func deserializer = GetDeserializer(identity, reader); - while (reader.Read()) - { - list.Add(deserializer(reader)); - } + return data.ToList(); + } + else + { + return data; } - return list; } + /// /// Return a typed list of objects, reader is closed after the call /// - public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true) + private static IEnumerable QueryInternal(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null) { + var identity = new Identity(sql, cnn, typeof(T), param == null ? null : param.GetType()); - if (!buffered) + var info = GetCacheInfo(param, identity); + + List paramInfos = null; + if (info.ParamReader != null) { - return EnumerateMapperQuery(cnn, sql, param, transaction); + paramInfos = info.ParamReader(param); } - var identity = new Identity(sql, cnn, typeof(T)); - var rval = new List(); + using (var reader = GetReader(cnn, transaction, sql, paramInfos)) + { + if (info.Deserializer == null) + { + info.Deserializer = GetDeserializer(identity, reader); + queryCache[identity] = info; + } + var deserializer = (Func)info.Deserializer; - using (var reader = GetReader(cnn, transaction, sql, GetParamInfo(param))) - { - Func deserializer = GetDeserializer(identity, reader); while (reader.Read()) { - rval.Add(deserializer(reader)); + yield return deserializer(reader); } } - return rval; + + } + + private static CacheInfo GetCacheInfo(object param, Identity identity) + { + CacheInfo info; + if (!queryCache.TryGetValue(identity, out info)) + { + info = new CacheInfo(); + if (param != null) + { + info.ParamReader = CreateParamInfoGenerator(param.GetType()); + } + } + return info; } public static List Query(this IDbConnection cnn, string sql, Action map, object param = null, IDbTransaction transaction = null) @@ -203,82 +244,27 @@ static class DynamicStub public static Type Type = typeof(DynamicStub); } - /// - /// Enumerates the query, keeping the reader open after it is called. Use when iterating through huge result sets . You should usually use ExecuteMapperQuery instead. - /// - static IEnumerable EnumerateMapperQuery(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null) + static Func GetDeserializer(Identity identity, IDataReader reader) { - var identity = new Identity(sql, cnn, typeof(T)); + object oDeserializer; - using (var reader = GetReader(cnn, transaction, sql, GetParamInfo(param))) + if (typeof(T) == DynamicStub.Type || typeof(T) == typeof(ExpandoObject)) { - Func deserializer = GetDeserializer(identity, reader); - while (reader.Read()) - { - yield return deserializer(reader); - } + oDeserializer = GetDynamicDeserializer(reader); } - } - - /// - /// Enumerates the query, keeping the reader open after it is called. Use when iterating through huge result sets. You should usually use ExecuteMapperQuery instead - /// - static IEnumerable EnumerateMapperQuery(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null) - { - var identity = new Identity(sql, cnn, DynamicStub.Type); - - using (var reader = GetReader(cnn, transaction, sql, GetParamInfo(param))) + else if (typeof(T).IsClass && typeof(T) != typeof(string)) { - Func deserializer = GetDeserializer(identity, reader); - while (reader.Read()) - { - yield return deserializer(reader); - } + oDeserializer = GetClassDeserializer(reader); } - } - - static Func GetDeserializer(Identity identity, IDataReader reader) - { - object oDeserializer; - if (!cachedSerializers.TryGetValue(identity, out oDeserializer)) + else { - if (typeof(T) == DynamicStub.Type || typeof(T) == typeof(ExpandoObject)) - { - oDeserializer = GetDynamicDeserializer(reader); - } - else if (typeof(T).IsClass && typeof(T) != typeof(string)) - { - oDeserializer = GetClassDeserializer(reader); - } - else - { - oDeserializer = GetStructDeserializer(reader); - } - - cachedSerializers[identity] = oDeserializer; + oDeserializer = GetStructDeserializer(reader); } + Func deserializer = (Func)oDeserializer; return deserializer; } - private static List GetParamInfo(object param) - { - Func> paramInfoGenerator; - List paramInfo = null; - - if (param != null) - { - if (!cachedParamReaders.TryGetValue(param.GetType(), out paramInfoGenerator)) - { - paramInfoGenerator = CreateParamInfoGenerator(param.GetType()); - cachedParamReaders[param.GetType()] = paramInfoGenerator; - } - paramInfo = paramInfoGenerator(param); - } - - return paramInfo; - } - private static object GetDynamicDeserializer(IDataReader reader) { List colNames = new List(); -- GitLab