diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index 5a5dd95130b82256f35418fa6c781224d867eda3..db1cbc32851e2bd3432bcbd271b58a866de37c90 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -662,11 +662,11 @@ private static object GetStructDeserializer(IDataReader reader) il.Emit(OpCodes.Stloc_0); var properties = typeof(T) .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - .Select(p => new + .Select(p => new { - p.Name, - Setter = p.DeclaringType == typeof(T) ? p.GetSetMethod(true) : p.DeclaringType.GetProperty(p.Name).GetSetMethod(true), - Type = p.PropertyType + p.Name, + Setter = p.DeclaringType == typeof(T) ? p.GetSetMethod(true) : p.DeclaringType.GetProperty(p.Name).GetSetMethod(true), + Type = p.PropertyType }) .Where(info => info.Setter != null) .ToList(); @@ -719,7 +719,15 @@ private static object GetStructDeserializer(IDataReader reader) il.Emit(OpCodes.Isinst, typeof(DBNull)); // stack is now [target][target][value-as-object][DBNull or null] il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [target][target][value-as-object] - il.Emit(OpCodes.Unbox_Any, item.Info.Type); // stack is now [target][target][typed-value] + // unbox nullable enums as the primitive, i.e. byte etc + var nullUnderlyingType = Nullable.GetUnderlyingType(item.Info.Type); + var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : item.Info.Type; + il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] + if (nullUnderlyingType != null && nullUnderlyingType.IsEnum) + { + il.Emit(OpCodes.Newobj, item.Info.Type.GetConstructor(new[] { nullUnderlyingType })); + } + il.Emit(OpCodes.Callvirt, item.Info.Setter); // stack is now [target] il.Emit(OpCodes.Br_S, finishLabel); // stack is now [target] @@ -752,7 +760,7 @@ private static object GetStructDeserializer(IDataReader reader) il.EndExceptionBlock(); il.Emit(OpCodes.Ldloc_1); // stack is empty - il.Emit(OpCodes.Ret); + il.Emit(OpCodes.Ret); return (Func)dm.CreateDelegate(typeof(Func)); }