Commit 11c29b4a authored by Marc Gravell's avatar Marc Gravell

Check ITypeHandler.Parse actually gets chance to parse values

parent 353b682f
...@@ -1741,11 +1741,21 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter ...@@ -1741,11 +1741,21 @@ private static CacheInfo GetCacheInfo(Identity identity, object exampleParameter
if (!(typeMap.ContainsKey(type) || type.IsEnum || type.FullName == LinqBinary || if (!(typeMap.ContainsKey(type) || type.IsEnum || type.FullName == LinqBinary ||
(type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum))) (type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum)))
{ {
ITypeHandler handler;
if (typeHandlers.TryGetValue(type, out handler))
{
return GetHandlerDeserializer(handler, type, startBound);
}
return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing); return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing);
} }
return GetStructDeserializer(type, underlyingType ?? type, startBound); return GetStructDeserializer(type, underlyingType ?? type, startBound);
} }
static Func<IDataReader, object> GetHandlerDeserializer(ITypeHandler handler, Type type, int startBound)
{
return (IDataReader reader) =>
handler.Parse(type, reader.GetValue(startBound));
}
#if !CSHARP30 #if !CSHARP30
private sealed partial class DapperTable private sealed partial class DapperTable
...@@ -3145,9 +3155,10 @@ public static void SetTypeMap(Type type, ITypeMap map) ...@@ -3145,9 +3155,10 @@ public static void SetTypeMap(Type type, ITypeMap map)
{ {
Type dataType = reader.GetFieldType(index); Type dataType = reader.GetFieldType(index);
TypeCode dataTypeCode = Type.GetTypeCode(dataType), unboxTypeCode = Type.GetTypeCode(unboxType); TypeCode dataTypeCode = Type.GetTypeCode(dataType), unboxTypeCode = Type.GetTypeCode(unboxType);
if (dataType == unboxType || dataTypeCode == unboxTypeCode || dataTypeCode == Type.GetTypeCode(nullUnderlyingType)) bool hasTypeHandler;
if ((hasTypeHandler = typeHandlers.ContainsKey(unboxType)) || dataType == unboxType || dataTypeCode == unboxTypeCode || dataTypeCode == Type.GetTypeCode(nullUnderlyingType))
{ {
if (typeHandlers.ContainsKey(unboxType)) if (hasTypeHandler)
{ {
#pragma warning disable 618 #pragma warning disable 618
il.EmitCall(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(unboxType).GetMethod("Parse"), null); // stack is now [target][target][typed-value] il.EmitCall(OpCodes.Call, typeof(TypeHandlerCache<>).MakeGenericType(unboxType).GetMethod("Parse"), null); // stack is now [target][target][typed-value]
......
...@@ -3098,6 +3098,54 @@ class PracticeRebateOrders ...@@ -3098,6 +3098,54 @@ class PracticeRebateOrders
public string TaxInvoiceNumber { get { return fTaxInvoiceNumber; } set { fTaxInvoiceNumber = value; } } public string TaxInvoiceNumber { get { return fTaxInvoiceNumber; } set { fTaxInvoiceNumber = value; } }
} }
public class RatingValueHandler : Dapper.SqlMapper.TypeHandler<RatingValue>
{
private RatingValueHandler() { }
public static readonly RatingValueHandler Default = new RatingValueHandler();
public override RatingValue Parse(object value)
{
if (value is Int32)
return new RatingValue() { Value = (Int32)value };
throw new FormatException("Invalid conversion to RatingValue");
}
public override void SetValue(System.Data.IDbDataParameter parameter, RatingValue value)
{
// ... null, range checks etc ...
parameter.DbType = System.Data.DbType.Int32;
parameter.Value = value.Value;
}
}
public class RatingValue
{
public Int32 Value { get; set; }
// ... some other properties etc ...
}
public class MyResult
{
public String CategoryName { get; set; }
public RatingValue CategoryRating { get; set; }
}
public void SO24740733_TestCustomValueHandler()
{
Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default);
var foo = connection.Query<MyResult>("SELECT 'Foo' AS CategoryName, 200 AS CategoryRating").Single();
foo.CategoryName.IsEqualTo("Foo");
foo.CategoryRating.Value.IsEqualTo(200);
}
public void SO24740733_TestCustomValueSingleColumn()
{
Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default);
var foo = connection.Query<RatingValue>("SELECT 200 AS CategoryRating").Single();
foo.Value.IsEqualTo(200);
}
#if POSTGRESQL #if POSTGRESQL
class Cat class Cat
......
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