Commit 06abcbdf authored by mgravell's avatar mgravell

oops, fix crappy perf; also take out all @ code from parameters'

parent 0a28a98e
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Text.RegularExpressions;
namespace Dapper namespace Dapper
{ {
...@@ -27,7 +28,7 @@ public interface IDynamicParameters ...@@ -27,7 +28,7 @@ public interface IDynamicParameters
static Link<Type, Action<IDbCommand, bool>> bindByNameCache; static Link<Type, Action<IDbCommand, bool>> bindByNameCache;
static Action<IDbCommand, bool> GetBindByName(Type commandType) static Action<IDbCommand, bool> GetBindByName(Type commandType)
{ {
if(commandType == null) return null; // GIGO if (commandType == null) return null; // GIGO
Action<IDbCommand, bool> action; Action<IDbCommand, bool> action;
if (Link<Type, Action<IDbCommand, bool>>.TryGet(bindByNameCache, commandType, out action)) if (Link<Type, Action<IDbCommand, bool>>.TryGet(bindByNameCache, commandType, out action))
{ {
...@@ -66,7 +67,7 @@ public static bool TryGet(Link<TKey, TValue> link, TKey key, out TValue value) ...@@ -66,7 +67,7 @@ public static bool TryGet(Link<TKey, TValue> link, TKey key, out TValue value)
{ {
while (link != null) while (link != null)
{ {
if ((object)key==(object)link.Key) if ((object)key == (object)link.Key)
{ {
value = link.Value; value = link.Value;
return true; return true;
...@@ -222,6 +223,7 @@ private Identity(string sql, string connectionString, Type type, Type parameters ...@@ -222,6 +223,7 @@ private Identity(string sql, string connectionString, Type type, Type parameters
this.connectionString = connectionString; this.connectionString = connectionString;
this.type = type; this.type = type;
this.parametersType = parametersType; this.parametersType = parametersType;
this.gridIndex = gridIndex;
unchecked unchecked
{ {
hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this
...@@ -247,18 +249,18 @@ public override bool Equals(object obj) ...@@ -247,18 +249,18 @@ public override bool Equals(object obj)
private readonly int hashCode, gridIndex; private readonly int hashCode, gridIndex;
private readonly Type type; private readonly Type type;
private readonly string connectionString; private readonly string connectionString;
internal readonly Type parametersType; internal readonly Type parametersType;
public override int GetHashCode() public override int GetHashCode()
{ {
return hashCode; return hashCode;
} }
public bool Equals(Identity other) public bool Equals(Identity other)
{ {
return return
other != null && other != null &&
gridIndex == other.gridIndex && gridIndex == other.gridIndex &&
type == other.type && type == other.type &&
sql == other.sql && sql == other.sql &&
connectionString == other.connectionString && connectionString == other.connectionString &&
parametersType == other.parametersType; parametersType == other.parametersType;
} }
...@@ -272,7 +274,7 @@ public bool Equals(Identity other) ...@@ -272,7 +274,7 @@ public bool Equals(Identity other)
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
...@@ -284,9 +286,9 @@ public bool Equals(Identity other) ...@@ -284,9 +286,9 @@ public bool Equals(Identity other)
var interfaces = multiExec.GetType().GetInterfaces(); var interfaces = multiExec.GetType().GetInterfaces();
var openType = typeof(IEnumerable<>); var openType = typeof(IEnumerable<>);
Type foundType = null; Type foundType = null;
for(int i = 0 ; i < interfaces.Length; i++) for (int i = 0; i < interfaces.Length; i++)
{ {
if(interfaces[i].IsGenericType && interfaces[i].GetGenericTypeDefinition() == openType) if (interfaces[i].IsGenericType && interfaces[i].GetGenericTypeDefinition() == openType)
{ // implementing more than one T is self-inflicted { // implementing more than one T is self-inflicted
foundType = interfaces[i].GetGenericArguments()[0]; foundType = interfaces[i].GetGenericArguments()[0];
identity = new Identity(sql, cnn, null, foundType, null); identity = new Identity(sql, cnn, null, foundType, null);
...@@ -312,7 +314,7 @@ public bool Equals(Identity other) ...@@ -312,7 +314,7 @@ public bool Equals(Identity other)
} }
} }
} }
} }
// nice and simple // nice and simple
...@@ -335,9 +337,9 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn ...@@ -335,9 +337,9 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
var data = QueryInternal<T>(cnn, sql, param as object, transaction, commandTimeout, commandType); var data = QueryInternal<T>(cnn, sql, param as object, transaction, commandTimeout, commandType);
return buffered ? data.ToList() : data; return buffered ? data.ToList() : data;
...@@ -350,10 +352,10 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn ...@@ -350,10 +352,10 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
Identity identity = new Identity(sql, cnn, typeof(GridReader), (object)param == null ? null : ((object)param).GetType(), null); Identity identity = new Identity(sql, cnn, typeof(GridReader), (object)param == null ? null : ((object)param).GetType(), null);
CacheInfo info = GetCacheInfo(identity); CacheInfo info = GetCacheInfo(identity);
...@@ -405,7 +407,6 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -405,7 +407,6 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
} }
} }
} }
clean = false;
} }
finally finally
{ // throw away query plan on failure - could { // throw away query plan on failure - could
...@@ -415,7 +416,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -415,7 +416,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
} }
} }
} }
/// <summary> /// <summary>
/// Maps a query to objects /// Maps a query to objects
/// </summary> /// </summary>
...@@ -434,9 +435,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -434,9 +435,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
return MultiMap<TFirst, TSecond, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); return MultiMap<TFirst, TSecond, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
} }
...@@ -445,9 +446,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -445,9 +446,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
return MultiMap<TFirst, TSecond, TThird, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); return MultiMap<TFirst, TSecond, TThird, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
} }
...@@ -456,9 +457,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -456,9 +457,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#if CSHARP30 #if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else #else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif #endif
) )
{ {
return MultiMap<TFirst, TSecond, TThird, TFourth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); return MultiMap<TFirst, TSecond, TThird, TFourth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
} }
...@@ -468,8 +469,8 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq ...@@ -468,8 +469,8 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
} }
#endif #endif
class DontMap {} class DontMap { }
static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>( static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(
this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType) this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
{ {
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType); var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType);
...@@ -490,7 +491,7 @@ class DontMap {} ...@@ -490,7 +491,7 @@ class DontMap {}
int current = 0; int current = 0;
var splits = splitOn.Split(',').ToArray(); var splits = splitOn.Split(',').ToArray();
var splitIndex = 0; var splitIndex = 0;
Func<int> nextSplit = () => Func<int> nextSplit = () =>
{ {
...@@ -503,7 +504,7 @@ class DontMap {} ...@@ -503,7 +504,7 @@ class DontMap {}
for (pos = current + 1; pos < reader.FieldCount; pos++) for (pos = current + 1; pos < reader.FieldCount; pos++)
{ {
// some people like ID some id ... assuming case insensitive splits for now // some people like ID some id ... assuming case insensitive splits for now
if (splitOn=="*" || string.Equals(reader.GetName(pos), currentSplit, StringComparison.InvariantCultureIgnoreCase)) if (splitOn == "*" || string.Equals(reader.GetName(pos), currentSplit, StringComparison.InvariantCultureIgnoreCase))
{ {
break; break;
} }
...@@ -554,7 +555,7 @@ class DontMap {} ...@@ -554,7 +555,7 @@ class DontMap {}
if (info.OtherDeserializers.Length == 1) if (info.OtherDeserializers.Length == 1)
{ {
mapIt = r => ((Func<TFirst, TSecond,TReturn>)map)(deserializer(r), deserializer2(r)); mapIt = r => ((Func<TFirst, TSecond, TReturn>)map)(deserializer(r), deserializer2(r));
} }
if (info.OtherDeserializers.Length > 1) if (info.OtherDeserializers.Length > 1)
...@@ -570,7 +571,7 @@ class DontMap {} ...@@ -570,7 +571,7 @@ class DontMap {}
var deserializer4 = (Func<IDataReader, TFourth>)info.OtherDeserializers[2]; var deserializer4 = (Func<IDataReader, TFourth>)info.OtherDeserializers[2];
if (info.OtherDeserializers.Length == 3) if (info.OtherDeserializers.Length == 3)
{ {
mapIt = r => ((Func<TFirst, TSecond, TThird, TFourth, TReturn>)map)(deserializer(r), deserializer2(r), deserializer3(r),deserializer4(r)); mapIt = r => ((Func<TFirst, TSecond, TThird, TFourth, TReturn>)map)(deserializer(r), deserializer2(r), deserializer3(r), deserializer4(r));
} }
if (info.OtherDeserializers.Length > 3) if (info.OtherDeserializers.Length > 3)
...@@ -579,7 +580,7 @@ class DontMap {} ...@@ -579,7 +580,7 @@ class DontMap {}
throw new NotSupportedException(); throw new NotSupportedException();
#else #else
var deserializer5 = (Func<IDataReader, TFifth>)info.OtherDeserializers[3]; var deserializer5 = (Func<IDataReader, TFifth>)info.OtherDeserializers[3];
mapIt = r => ((Func<TFirst, TSecond, TThird, TFourth,TFifth,TReturn>)map)(deserializer(r), deserializer2(r), deserializer3(r), deserializer4(r),deserializer5(r)); mapIt = r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>)map)(deserializer(r), deserializer2(r), deserializer3(r), deserializer4(r), deserializer5(r));
#endif #endif
} }
} }
...@@ -605,8 +606,8 @@ class DontMap {} ...@@ -605,8 +606,8 @@ class DontMap {}
} }
} }
} }
} }
private static CacheInfo GetCacheInfo(Identity identity) private static CacheInfo GetCacheInfo(Identity identity)
{ {
CacheInfo info; CacheInfo info;
...@@ -633,13 +634,13 @@ private static CacheInfo GetCacheInfo(Identity identity) ...@@ -633,13 +634,13 @@ private static CacheInfo GetCacheInfo(Identity identity)
{ {
#if !CSHARP30 #if !CSHARP30
// dynamic is passed in as Object ... by c# design // dynamic is passed in as Object ... by c# design
if (typeof (T) == typeof (object) if (typeof(T) == typeof(object)
|| typeof (T) == typeof (FastExpando)) || typeof(T) == typeof(FastExpando))
{ {
return GetDynamicDeserializer<T>(reader, startBound, length, returnNullIfFirstMissing); return GetDynamicDeserializer<T>(reader, startBound, length, returnNullIfFirstMissing);
} }
#endif #endif
if (typeof (T).IsClass && typeof (T) != typeof (string)) if (typeof(T).IsClass && typeof(T) != typeof(string))
{ {
return GetClassDeserializer<T>(reader, startBound, length, returnNullIfFirstMissing); return GetClassDeserializer<T>(reader, startBound, length, returnNullIfFirstMissing);
} }
...@@ -653,7 +654,7 @@ private class FastExpando : System.Dynamic.DynamicObject, IDictionary<string, ob ...@@ -653,7 +654,7 @@ private class FastExpando : System.Dynamic.DynamicObject, IDictionary<string, ob
public static FastExpando Attach(IDictionary<string, object> data) public static FastExpando Attach(IDictionary<string, object> data)
{ {
return new FastExpando {data = data}; return new FastExpando { data = data };
} }
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value) public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value)
...@@ -779,23 +780,23 @@ IEnumerator IEnumerable.GetEnumerator() ...@@ -779,23 +780,23 @@ IEnumerator IEnumerable.GetEnumerator()
length = reader.FieldCount - startBound; length = reader.FieldCount - startBound;
} }
return return
r => r =>
{ {
IDictionary<string, object> row = new Dictionary<string,object>(length); IDictionary<string, object> row = new Dictionary<string, object>(length);
for (var i = startBound; i < startBound + length; i++) for (var i = startBound; i < startBound + length; i++)
{ {
var tmp = r.GetValue(i); var tmp = r.GetValue(i);
tmp = tmp == DBNull.Value ? null : tmp; tmp = tmp == DBNull.Value ? null : tmp;
row[r.GetName(i)] = tmp; row[r.GetName(i)] = tmp;
if (returnNullIfFirstMissing && i == startBound && tmp == null) if (returnNullIfFirstMissing && i == startBound && tmp == null)
{ {
return default(T); return default(T);
} }
} }
//we know this is an object so it will not box //we know this is an object so it will not box
return (T)(object)FastExpando.Attach(row); return (T)(object)FastExpando.Attach(row);
}; };
} }
#endif #endif
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
...@@ -830,17 +831,20 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -830,17 +831,20 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
if (count == 0) if (count == 0)
{ {
command.CommandText = command.CommandText.Replace(namePrefix, "(SELECT NULL WHERE 1 = 0)"); command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), "(SELECT NULL WHERE 1 = 0)");
} }
else else
{ {
var sb = new StringBuilder("(").Append(namePrefix).Append(1); command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), match =>
for (int i = 2; i <= count; i++)
{ {
sb.Append(',').Append(namePrefix).Append(i); var grp = match.Value;
} var sb = new StringBuilder("(").Append(grp).Append(1);
string inQuery = sb.Append(')').ToString(); for (int i = 2; i <= count; i++)
command.CommandText = command.CommandText.Replace(namePrefix, inQuery); {
sb.Append(',').Append(grp).Append(i);
}
return sb.Append(')').ToString();
});
} }
} }
...@@ -861,16 +865,16 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -861,16 +865,16 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
il.Emit(OpCodes.Ldarg_0); // stack is now [command] il.Emit(OpCodes.Ldarg_0); // stack is now [command]
il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters] il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetProperty("Parameters").GetGetMethod(), null); // stack is now [parameters]
foreach (var prop in type.GetProperties().OrderBy(p => p.Name)) foreach (var prop in type.GetProperties().OrderBy(p => p.Name))
{ {
if(prop.PropertyType == typeof(DbString)) if (prop.PropertyType == typeof(DbString))
{ {
il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [typed-param] il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [typed-param]
il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [dbstring] il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [dbstring]
il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [dbstring] [command] il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [dbstring] [command]
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [dbstring] [command] [name] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [dbstring] [command] [name]
il.EmitCall(OpCodes.Callvirt, typeof(DbString).GetMethod("AddParameter"), null); // stack is now [parameters] il.EmitCall(OpCodes.Callvirt, typeof(DbString).GetMethod("AddParameter"), null); // stack is now [parameters]
continue; continue;
} }
...@@ -879,7 +883,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -879,7 +883,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
{ {
// this actually represents special handling for list types; // this actually represents special handling for list types;
il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [command] il.Emit(OpCodes.Ldarg_0); // stack is now [parameters] [command]
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [command] [name] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [command] [name]
il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [command] [name] [typed-param] il.Emit(OpCodes.Ldloc_0); // stack is now [parameters] [command] [name] [typed-param]
il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [command] [name] [typed-value] il.Emit(OpCodes.Callvirt, prop.GetGetMethod()); // stack is [parameters] [command] [name] [typed-value]
if (prop.PropertyType.IsValueType) if (prop.PropertyType.IsValueType)
...@@ -895,7 +899,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -895,7 +899,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod("CreateParameter"), null);// stack is now [parameters] [parameters] [parameter] il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod("CreateParameter"), null);// stack is now [parameters] [parameters] [parameter]
il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter]
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] il.Emit(OpCodes.Ldstr, prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name]
il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("ParameterName").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter] il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty("ParameterName").GetSetMethod(), null);// stack is now [parameters] [parameters] [parameter]
il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter] il.Emit(OpCodes.Dup);// stack is now [parameters] [parameters] [parameter] [parameter]
...@@ -1013,7 +1017,7 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction tranaction, ...@@ -1013,7 +1017,7 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction tranaction,
private static Func<IDataReader, T> GetStructDeserializer<T>(int index) private static Func<IDataReader, T> GetStructDeserializer<T>(int index)
{ {
return r => return r =>
{ {
var val = r.GetValue(index); var val = r.GetValue(index);
if (val == DBNull.Value) if (val == DBNull.Value)
...@@ -1033,9 +1037,9 @@ static readonly MethodInfo ...@@ -1033,9 +1037,9 @@ static readonly MethodInfo
#if CSHARP30 #if CSHARP30
IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing
#else #else
IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false
#endif #endif
) )
{ {
var dm = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(T), new[] { typeof(IDataReader) }, true); var dm = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(T), new[] { typeof(IDataReader) }, true);
...@@ -1082,7 +1086,7 @@ static readonly MethodInfo ...@@ -1082,7 +1086,7 @@ static readonly MethodInfo
// stack is empty // stack is empty
il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); // stack is now [target] il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); // stack is now [target]
bool first = true; bool first = true;
var @allDone = il.DefineLabel(); var allDone = il.DefineLabel();
foreach (var item in setters) foreach (var item in setters)
{ {
if (item.Property != null || item.Field != null) if (item.Property != null || item.Field != null)
...@@ -1124,7 +1128,7 @@ static readonly MethodInfo ...@@ -1124,7 +1128,7 @@ static readonly MethodInfo
il.Emit(OpCodes.Pop); // stack is now [target][target] il.Emit(OpCodes.Pop); // stack is now [target][target]
il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [target][target][enum-type-token] il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [target][target][enum-type-token]
il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);// stack is now [target][target][enum-type] il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);// stack is now [target][target][enum-type]
il.Emit(OpCodes.Ldloc_2); // stack is now [target][target][enum-type][string] il.Emit(OpCodes.Ldloc_2); // stack is now [target][target][enum-type][string]
...@@ -1144,7 +1148,7 @@ static readonly MethodInfo ...@@ -1144,7 +1148,7 @@ static readonly MethodInfo
else else
{ {
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target] il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
} }
il.Emit(OpCodes.Br_S, finishLabel); il.Emit(OpCodes.Br_S, finishLabel);
...@@ -1175,7 +1179,7 @@ static readonly MethodInfo ...@@ -1175,7 +1179,7 @@ static readonly MethodInfo
il.Emit(OpCodes.Pop); il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldnull); // stack is now [null] il.Emit(OpCodes.Ldnull); // stack is now [null]
il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Br, @allDone); il.Emit(OpCodes.Br, allDone);
} }
il.MarkLabel(finishLabel); il.MarkLabel(finishLabel);
...@@ -1184,7 +1188,7 @@ static readonly MethodInfo ...@@ -1184,7 +1188,7 @@ static readonly MethodInfo
index += 1; index += 1;
} }
il.Emit(OpCodes.Stloc_1); // stack is empty il.Emit(OpCodes.Stloc_1); // stack is empty
il.MarkLabel(@allDone); il.MarkLabel(allDone);
il.BeginCatchBlock(typeof(Exception)); // stack is Exception il.BeginCatchBlock(typeof(Exception)); // stack is Exception
il.Emit(OpCodes.Ldloc_0); // stack is Exception, index il.Emit(OpCodes.Ldloc_0); // stack is Exception, index
il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader
...@@ -1214,7 +1218,7 @@ public static void ThrowDataException(Exception ex, int index, IDataReader reade ...@@ -1214,7 +1218,7 @@ public static void ThrowDataException(Exception ex, int index, IDataReader reade
value = Convert.ToString(val) + " - " + Type.GetTypeCode(val.GetType()); value = Convert.ToString(val) + " - " + Type.GetTypeCode(val.GetType());
} }
} }
throw new DataException(string.Format("Error parsing column {0} ({1}={2})", index, name,value), ex); throw new DataException(string.Format("Error parsing column {0} ({1}={2})", index, name, value), ex);
} }
private static void EmitInt32(ILGenerator il, int value) private static void EmitInt32(ILGenerator il, int value)
{ {
...@@ -1277,7 +1281,7 @@ public IEnumerable<T> Read<T>() ...@@ -1277,7 +1281,7 @@ public IEnumerable<T> Read<T>()
private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, T> deserializer, Identity typedIdentity) private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, T> deserializer, Identity typedIdentity)
{ {
bool clean = true; bool clean = true;
try try
{ {
...@@ -1333,7 +1337,7 @@ public void Dispose() ...@@ -1333,7 +1337,7 @@ public void Dispose()
} }
public class DynamicParameters : SqlMapper.IDynamicParameters public class DynamicParameters : SqlMapper.IDynamicParameters
{ {
Dictionary<string, ParamInfo> parameters = new Dictionary<string,ParamInfo>(); Dictionary<string, ParamInfo> parameters = new Dictionary<string, ParamInfo>();
class ParamInfo class ParamInfo
{ {
...@@ -1356,11 +1360,11 @@ public DynamicParameters(object template) ...@@ -1356,11 +1360,11 @@ public DynamicParameters(object template)
if (!prop.CanRead) continue; if (!prop.CanRead) continue;
var idx = prop.GetIndexParameters(); var idx = prop.GetIndexParameters();
if (idx != null && idx.Length != 0) continue; if (idx != null && idx.Length != 0) continue;
Add("@" + prop.Name, prop.GetValue(template, null), null, ParameterDirection.Input, null); Add(prop.Name, prop.GetValue(template, null), null, ParameterDirection.Input, null);
} }
foreach (FieldInfo field in template.GetType().GetFields(bindingFlags)) foreach (FieldInfo field in template.GetType().GetFields(bindingFlags))
{ {
Add("@" + field.Name, field.GetValue(template), null, ParameterDirection.Input, null); Add(field.Name, field.GetValue(template), null, ParameterDirection.Input, null);
} }
} }
...@@ -1371,13 +1375,27 @@ public DynamicParameters(object template) ...@@ -1371,13 +1375,27 @@ public DynamicParameters(object template)
#if CSHARP30 #if CSHARP30
string name, object value, DbType? dbType, ParameterDirection? direction, int? size string name, object value, DbType? dbType, ParameterDirection? direction, int? size
#else #else
string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null
#endif #endif
) )
{ {
parameters[name] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size }; parameters[Clean(name)] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size };
} }
static string Clean(string name)
{
if (!string.IsNullOrEmpty(name))
{
switch (name[0])
{
case '@':
case ':':
case '?':
return name.Substring(1);
}
}
return name;
}
void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command) void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command)
{ {
...@@ -1388,7 +1406,7 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command) ...@@ -1388,7 +1406,7 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command)
p.ParameterName = param.Name; p.ParameterName = param.Name;
p.Value = val ?? DBNull.Value; p.Value = val ?? DBNull.Value;
p.Direction = param.ParameterDirection; p.Direction = param.ParameterDirection;
var s = val as string; var s = val as string;
if (s != null) if (s != null)
{ {
if (s.Length <= 4000) if (s.Length <= 4000)
...@@ -1411,7 +1429,7 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command) ...@@ -1411,7 +1429,7 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command)
public T Get<T>(string name) public T Get<T>(string name)
{ {
return (T)parameters[name].AttachedParam.Value; return (T)parameters[Clean(name)].AttachedParam.Value;
} }
} }
public sealed class DbString public sealed class DbString
......
...@@ -57,7 +57,7 @@ public static void IsNull(this object obj) ...@@ -57,7 +57,7 @@ public static void IsNull(this object obj)
class Tests class Tests
{ {
SqlConnection connection = Program.GetOpenConnection(); SqlConnection connection = Program.GetOpenConnection();
public void SelectListInt() public void SelectListInt()
...@@ -72,11 +72,17 @@ public void PassInIntArray() ...@@ -72,11 +72,17 @@ public void PassInIntArray()
.IsSequenceEqualTo(new[] { 1, 2, 3 }); .IsSequenceEqualTo(new[] { 1, 2, 3 });
} }
public void PassInEmptyIntArray()
{
connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[0] })
.IsSequenceEqualTo(new int[0]);
}
public void TestReadMultipleIntegersWithSplitOnAny() public void TestReadMultipleIntegersWithSplitOnAny()
{ {
connection.Query<int,int,int,Tuple<int,int,int>>( connection.Query<int, int, int, Tuple<int, int, int>>(
"select 1,2,3 union all select 4,5,6", Tuple.Create, splitOn: "*") "select 1,2,3 union all select 4,5,6", Tuple.Create, splitOn: "*")
.IsSequenceEqualTo(new[] {Tuple.Create(1,2,3), Tuple.Create(4,5,6)}); .IsSequenceEqualTo(new[] { Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6) });
} }
public void TestDoubleParam() public void TestDoubleParam()
...@@ -131,7 +137,7 @@ public class Dog ...@@ -131,7 +137,7 @@ public class Dog
public void TestExtraFields() public void TestExtraFields()
{ {
var guid = Guid.NewGuid(); var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { Id = guid}); var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { Id = guid });
dog.Count() dog.Count()
.IsEqualTo(1); .IsEqualTo(1);
...@@ -148,7 +154,7 @@ public void TestStrongType() ...@@ -148,7 +154,7 @@ public void TestStrongType()
{ {
var guid = Guid.NewGuid(); var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
dog.Count() dog.Count()
.IsEqualTo(1); .IsEqualTo(1);
...@@ -167,7 +173,7 @@ public void TestSimpleNull() ...@@ -167,7 +173,7 @@ public void TestSimpleNull()
public void TestExpando() public void TestExpando()
{ {
var rows = connection.Query("select 1 A, 2 B union all select 3, 4").ToList(); var rows = connection.Query("select 1 A, 2 B union all select 3, 4").ToList();
((int)rows[0].A) ((int)rows[0].A)
.IsEqualTo(1); .IsEqualTo(1);
...@@ -183,11 +189,11 @@ public void TestExpando() ...@@ -183,11 +189,11 @@ public void TestExpando()
public void TestStringList() public void TestStringList()
{ {
connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new {strings = new[] {"a","b","c"}}) connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new[] { "a", "b", "c" } })
.IsSequenceEqualTo(new[] {"a","b","c"}); .IsSequenceEqualTo(new[] { "a", "b", "c" });
connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new string[0] }) connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new string[0] })
.IsSequenceEqualTo(new string[0]); .IsSequenceEqualTo(new string[0]);
} }
public void TestExecuteCommand() public void TestExecuteCommand()
...@@ -199,12 +205,12 @@ public void TestExecuteCommand() ...@@ -199,12 +205,12 @@ public void TestExecuteCommand()
insert #t insert #t
select @a a union all select @b select @a a union all select @b
set nocount on set nocount on
drop table #t", new {a=1, b=2 }).IsEqualTo(2); drop table #t", new { a = 1, b = 2 }).IsEqualTo(2);
} }
public void TestExecuteCommandWithHybridParameters() public void TestExecuteCommandWithHybridParameters()
{ {
var p = new DynamicParameters(new { a = 1, b = 2 }); var p = new DynamicParameters(new { a = 1, b = 2 });
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Execute(@"set @c = @a + @b", p); connection.Execute(@"set @c = @a + @b", p);
p.Get<int>("@c").IsEqualTo(3); p.Get<int>("@c").IsEqualTo(3);
} }
...@@ -218,7 +224,7 @@ public void TestExecuteMultipleCommand() ...@@ -218,7 +224,7 @@ public void TestExecuteMultipleCommand()
} }
public void TestMassiveStrings() public void TestMassiveStrings()
{ {
var str = new string('X', 20000); var str = new string('X', 20000);
connection.Query<string>("select @a", new { a = str }).First() connection.Query<string>("select @a", new { a = str }).First()
.IsEqualTo(str); .IsEqualTo(str);
...@@ -294,12 +300,12 @@ public void TestEnumerationDynamic() ...@@ -294,12 +300,12 @@ public void TestEnumerationDynamic()
} }
class User class User
{ {
public int Id { get; set; } public int Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
} }
class Post class Post
{ {
public int Id { get; set; } public int Id { get; set; }
public User Owner { get; set; } public User Owner { get; set; }
...@@ -320,14 +326,14 @@ public void TestMultiMap() ...@@ -320,14 +326,14 @@ public void TestMultiMap()
"; ";
connection.Execute(createSql); connection.Execute(createSql);
var sql = var sql =
@"select * from #Posts p @"select * from #Posts p
left join #Users u on u.Id = p.OwnerId left join #Users u on u.Id = p.OwnerId
Order by p.Id"; Order by p.Id";
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList(); var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
var p = data.First(); var p = data.First();
p.Content.IsEqualTo("Sams Post1"); p.Content.IsEqualTo("Sams Post1");
p.Id.IsEqualTo(1); p.Id.IsEqualTo(1);
p.Owner.Name.IsEqualTo("Sam"); p.Owner.Name.IsEqualTo("Sam");
...@@ -403,7 +409,7 @@ public void TestFieldsAndPrivates() ...@@ -403,7 +409,7 @@ public void TestFieldsAndPrivates()
var data = connection.Query<TestFieldCaseAndPrivatesEntity>( var data = connection.Query<TestFieldCaseAndPrivatesEntity>(
@"select a=1,b=2,c=3,d=4,f='5'").Single(); @"select a=1,b=2,c=3,d=4,f='5'").Single();
data.a.IsEqualTo(1); data.a.IsEqualTo(1);
data.GetB().IsEqualTo(2); data.GetB().IsEqualTo(2);
data.c.IsEqualTo(3); data.c.IsEqualTo(3);
...@@ -457,13 +463,13 @@ public void TestMultiMappingVariations() ...@@ -457,13 +463,13 @@ public void TestMultiMappingVariations()
Assert.IsEqualTo(order.Creator.Id, 3); Assert.IsEqualTo(order.Creator.Id, 3);
Assert.IsEqualTo(order.Creator.Content, "c"); Assert.IsEqualTo(order.Creator.Content, "c");
order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator, address) => order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator, address) =>
{ {
o.Owner = owner; o.Owner = owner;
o.Creator = creator; o.Creator = creator;
o.Owner.Address = address; o.Owner.Address = address;
return o; return o;
}).First(); }).First();
Assert.IsEqualTo(order.Id, 1); Assert.IsEqualTo(order.Id, 1);
Assert.IsEqualTo(order.Content, "a"); Assert.IsEqualTo(order.Content, "a");
...@@ -535,7 +541,7 @@ public void MultiRSSqlCE() ...@@ -535,7 +541,7 @@ public void MultiRSSqlCE()
var cnnStr = "Data Source = Test.sdf;"; var cnnStr = "Data Source = Test.sdf;";
var engine = new SqlCeEngine(cnnStr); var engine = new SqlCeEngine(cnnStr);
engine.CreateDatabase(); engine.CreateDatabase();
using (var cnn = new SqlCeConnection(cnnStr)) using (var cnn = new SqlCeConnection(cnnStr))
{ {
cnn.Open(); cnn.Open();
...@@ -557,8 +563,8 @@ public void MultiRSSqlCE() ...@@ -557,8 +563,8 @@ public void MultiRSSqlCE()
} }
enum TestEnum : byte enum TestEnum : byte
{ {
Bla = 1 Bla = 1
} }
class TestEnumClass class TestEnumClass
{ {
...@@ -591,21 +597,21 @@ public void TestEnumStrings() ...@@ -591,21 +597,21 @@ public void TestEnumStrings()
public void TestSupportForParamDictionary() public void TestSupportForParamDictionary()
{ {
var p = new DynamicParameters(); var p = new DynamicParameters();
p.Add("@name", "bob"); p.Add("name", "bob");
p.Add("@age", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add("age", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Query<string>("set @age = 11 select @name", p).First().IsEqualTo("bob"); connection.Query<string>("set @age = 11 select @name", p).First().IsEqualTo("bob");
p.Get<int>("@age").IsEqualTo(11); p.Get<int>("age").IsEqualTo(11);
} }
public void TestProcSupport() public void TestProcSupport()
{ {
var p = new DynamicParameters(); var p = new DynamicParameters();
p.Add("@a", 11); p.Add("a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output); p.Add("b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
connection.Execute(@"create proc #TestProc connection.Execute(@"create proc #TestProc
@a int, @a int,
...@@ -618,8 +624,8 @@ select 1111 ...@@ -618,8 +624,8 @@ select 1111
end"); end");
connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(1111); connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(1111);
p.Get<int>("@c").IsEqualTo(11); p.Get<int>("c").IsEqualTo(11);
p.Get<int>("@b").IsEqualTo(999); p.Get<int>("b").IsEqualTo(999);
} }
...@@ -664,14 +670,14 @@ class Extra ...@@ -664,14 +670,14 @@ class Extra
public void TestFlexibleMultiMapping() public void TestFlexibleMultiMapping()
{ {
var sql = var sql =
@"select @"select
1 as PersonId, 'bob' as Name, 1 as PersonId, 'bob' as Name,
2 as AddressId, 'abc street' as Name, 1 as PersonId, 2 as AddressId, 'abc street' as Name, 1 as PersonId,
3 as Id, 'fred' as Name 3 as Id, 'fred' as Name
"; ";
var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address,Extra>> var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
(sql, (p,a,e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First(); (sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First();
personWithAddress.Item1.PersonId.IsEqualTo(1); personWithAddress.Item1.PersonId.IsEqualTo(1);
personWithAddress.Item1.Name.IsEqualTo("bob"); personWithAddress.Item1.Name.IsEqualTo("bob");
...@@ -695,11 +701,11 @@ public void TestFastExpandoSupportsIDictionary() ...@@ -695,11 +701,11 @@ public void TestFastExpandoSupportsIDictionary()
class PrivateDan class PrivateDan
{ {
public int Shadow { get; set; } public int Shadow { get; set; }
private string ShadowInDB private string ShadowInDB
{ {
set set
{ {
Shadow = value == "one" ? 1 : 0; Shadow = value == "one" ? 1 : 0;
} }
} }
} }
...@@ -736,11 +742,11 @@ public void AddParameters(IDbCommand command) ...@@ -736,11 +742,11 @@ public void AddParameters(IDbCommand command)
} }
// Add the table parameter. // Add the table parameter.
var p = sqlCommand.Parameters.Add("@ints", SqlDbType.Structured); var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
p.Direction = ParameterDirection.Input; p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type"; p.TypeName = "int_list_type";
p.Value = number_list; p.Value = number_list;
} }
} }
...@@ -796,7 +802,7 @@ public void ParentChildIdentityAssociations() ...@@ -796,7 +802,7 @@ public void ParentChildIdentityAssociations()
return found; return found;
}).Distinct().ToDictionary(p => p.Id); }).Distinct().ToDictionary(p => p.Id);
parents.Count().IsEqualTo(3); parents.Count().IsEqualTo(3);
parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1,2,4}).IsTrue(); parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1, 2, 4 }).IsTrue();
parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue(); parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue();
parents[3].Children.Select(c => c.Id).SequenceEqual(new[] { 5 }).IsTrue(); parents[3].Children.Select(c => c.Id).SequenceEqual(new[] { 5 }).IsTrue();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment