Commit a890c30e authored by Marc Gravell's avatar Marc Gravell

Make use of delegate variance, so the actual delegate stored is a...

Make use of delegate variance, so the actual delegate stored is a Func<IDataReader, YourType>; this makes it possible to efficiently expose GetRowParser<T> without any extra allocations
parent 7df23a74
......@@ -5,7 +5,7 @@
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0",
"summary": "A high performance Micro-ORM",
"description": "A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..",
"version": "1.50-beta6",
"version": "1.50-beta7",
"title": "Dapper dot net (strong named)",
"tags": [ "orm", "sql", "micro-orm" ],
"copyright": "2015 Stack Exchange, Inc.",
......
......@@ -14,6 +14,10 @@ public void GetSameReaderForSameShape()
var origReader = connection.ExecuteReader("select 'abc' as Name, 123 as Id");
var origParser = origReader.GetRowParser(typeof(HazNameId));
var typedParser = origReader.GetRowParser<HazNameId>();
ReferenceEquals(origParser, typedParser).IsEqualTo(true);
var list = origReader.Parse<HazNameId>().ToList();
list.Count.IsEqualTo(1);
list[0].Name.IsEqualTo("abc");
......@@ -47,8 +51,8 @@ union all
{
if (reader.Read())
{
var toFoo = reader.GetRowParser(typeof(Discriminated_Foo));
var toBar = reader.GetRowParser(typeof(Discriminated_Bar));
var toFoo = reader.GetRowParser<Discriminated_BaseType>(typeof(Discriminated_Foo));
var toBar = reader.GetRowParser<Discriminated_BaseType>(typeof(Discriminated_Bar));
var col = reader.GetOrdinal("Type");
do
......@@ -56,10 +60,10 @@ union all
switch (reader.GetInt32(col))
{
case 1:
result.Add((Discriminated_BaseType)toFoo(reader));
result.Add(toFoo(reader));
break;
case 2:
result.Add((Discriminated_BaseType)toBar(reader));
result.Add(toBar(reader));
break;
}
} while (reader.Read());
......
......@@ -49,5 +49,19 @@ public static IEnumerable<dynamic> Parse(this IDataReader reader)
{
return GetDeserializer(type, reader, startIndex, length, returnNullIfFirstMissing);
}
public static Func<IDataReader, T> GetRowParser<T>(this IDataReader reader, Type concreteType = null,
int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false)
{
if (concreteType == null) concreteType = typeof(T);
var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing);
if (concreteType.IsValueType())
{
return _ => (T)func(_);
}
else
{
return (Func<IDataReader, T>)(Delegate)func;
}
}
}
}
......@@ -2651,7 +2651,8 @@ public static void SetTypeMap(Type type, ITypeMap map)
Type type, IDataReader reader, int startBound = 0, int length = -1, bool returnNullIfFirstMissing = false
)
{
var dm = new DynamicMethod($"Deserialize{Guid.NewGuid()}", typeof(object), new[] { typeof(IDataReader) }, true);
var returnType = type.IsValueType() ? typeof(object) : type;
var dm = new DynamicMethod($"Deserialize{Guid.NewGuid()}", returnType, new[] { typeof(IDataReader) }, true);
var il = dm.GetILGenerator();
il.DeclareLocal(typeof(int));
il.DeclareLocal(type);
......@@ -2958,7 +2959,8 @@ public static void SetTypeMap(Type type, ITypeMap map)
}
il.Emit(OpCodes.Ret);
return (Func<IDataReader, object>)dm.CreateDelegate(typeof(Func<IDataReader, object>));
var funcType = System.Linq.Expressions.Expression.GetFuncType(typeof(IDataReader), returnType);
return (Func<IDataReader, object>)dm.CreateDelegate(funcType);
}
private static void FlexibleConvertBoxedFromHeadOfStack(ILGenerator il, Type from, Type to, Type via)
......
......@@ -5,7 +5,7 @@
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0",
"summary": "A high performance Micro-ORM",
"description": "A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..",
"version": "1.50-beta6",
"version": "1.50-beta7",
"title": "Dapper dot net",
"tags": [ "orm", "sql", "micro-orm" ],
"copyright": "2015 Stack Exchange, Inc.",
......
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