Commit 77dde933 authored by unknown's avatar unknown

Support enums (and nullable enums) in Query<T>, and check (extra tests) that...

Support enums (and nullable enums) in Query<T>, and check (extra tests) that they work fine for regular T with an enum / nullable-enum member
parent 5f5aa708
...@@ -929,12 +929,13 @@ private static CacheInfo GetCacheInfo(Identity identity) ...@@ -929,12 +929,13 @@ private static CacheInfo GetCacheInfo(Identity identity)
return GetDynamicDeserializer(reader, startBound, length, returnNullIfFirstMissing); return GetDynamicDeserializer(reader, startBound, length, returnNullIfFirstMissing);
} }
#endif #endif
Type underlyingType = null;
if (!(typeMap.ContainsKey(type) || type.FullName == LinqBinary)) if (!(typeMap.ContainsKey(type) || type.IsEnum || type.FullName == LinqBinary ||
(type.IsValueType && (underlyingType = Nullable.GetUnderlyingType(type)) != null && underlyingType.IsEnum)))
{ {
return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing); return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing);
} }
return GetStructDeserializer(type, startBound); return GetStructDeserializer(type, underlyingType ?? type, startBound);
} }
#if !CSHARP30 #if !CSHARP30
...@@ -1395,7 +1396,7 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction, ...@@ -1395,7 +1396,7 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction,
} }
} }
private static Func<IDataReader, object> GetStructDeserializer(Type type, int index) private static Func<IDataReader, object> GetStructDeserializer(Type type, Type effectiveType, int index)
{ {
// no point using special per-type handling here; it boils down to the same, plus not all are supported anyway (see: SqlDataReader.GetChar - not supported!) // no point using special per-type handling here; it boils down to the same, plus not all are supported anyway (see: SqlDataReader.GetChar - not supported!)
#pragma warning disable 618 #pragma warning disable 618
...@@ -1412,6 +1413,15 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction, ...@@ -1412,6 +1413,15 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction,
return r => Activator.CreateInstance(type, r.GetValue(index)); return r => Activator.CreateInstance(type, r.GetValue(index));
} }
#pragma warning restore 618 #pragma warning restore 618
if (effectiveType.IsEnum)
{ // assume the value is returned as the correct type (int/byte/etc), but box back to the typed enum
return r =>
{
var val = r.GetValue(index);
return val is DBNull ? null : Enum.ToObject(effectiveType, val);
};
}
return r => return r =>
{ {
var val = r.GetValue(index); var val = r.GetValue(index);
......
...@@ -1378,10 +1378,9 @@ public void TestInt16Usage() ...@@ -1378,10 +1378,9 @@ public void TestInt16Usage()
connection.Query<short?>("select cast(42 as smallint)").Single().IsEqualTo((short?)42); connection.Query<short?>("select cast(42 as smallint)").Single().IsEqualTo((short?)42);
connection.Query<short?>("select cast(null as smallint)").Single().IsEqualTo((short?)null); connection.Query<short?>("select cast(null as smallint)").Single().IsEqualTo((short?)null);
// hmmm.... these don't work currently... adding TODO connection.Query<ShortEnum>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum)42);
//connection.Query<ShortEnum>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum)42); connection.Query<ShortEnum?>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum?)42);
//connection.Query<ShortEnum?>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum?)42); connection.Query<ShortEnum?>("select cast(null as smallint)").Single().IsEqualTo((ShortEnum?)null);
//connection.Query<ShortEnum?>("select cast(null as smallint)").Single().IsEqualTo((ShortEnum?)null);
var row = var row =
connection.Query<WithInt16Values>( connection.Query<WithInt16Values>(
...@@ -1401,7 +1400,34 @@ public void TestInt16Usage() ...@@ -1401,7 +1400,34 @@ public void TestInt16Usage()
row.NonNullableInt16Enum.IsEqualTo(ShortEnum.Six); row.NonNullableInt16Enum.IsEqualTo(ShortEnum.Six);
row.NullableInt16Enum.IsEqualTo((ShortEnum?)null); row.NullableInt16Enum.IsEqualTo((ShortEnum?)null);
} }
public void TestInt32Usage()
{
connection.Query<int>("select cast(42 as int)").Single().IsEqualTo((int)42);
connection.Query<int?>("select cast(42 as int)").Single().IsEqualTo((int?)42);
connection.Query<int?>("select cast(null as int)").Single().IsEqualTo((int?)null);
connection.Query<IntEnum>("select cast(42 as int)").Single().IsEqualTo((IntEnum)42);
connection.Query<IntEnum?>("select cast(42 as int)").Single().IsEqualTo((IntEnum?)42);
connection.Query<IntEnum?>("select cast(null as int)").Single().IsEqualTo((IntEnum?)null);
var row =
connection.Query<WithInt32Values>(
"select cast(1 as int) as NonNullableInt32, cast(2 as int) as NullableInt32, cast(3 as int) as NonNullableInt32Enum, cast(4 as int) as NullableInt32Enum")
.Single();
row.NonNullableInt32.IsEqualTo((int)1);
row.NullableInt32.IsEqualTo((int)2);
row.NonNullableInt32Enum.IsEqualTo(IntEnum.Three);
row.NullableInt32Enum.IsEqualTo(IntEnum.Four);
row =
connection.Query<WithInt32Values>(
"select cast(5 as int) as NonNullableInt32, cast(null as int) as NullableInt32, cast(6 as int) as NonNullableInt32Enum, cast(null as int) as NullableInt32Enum")
.Single();
row.NonNullableInt32.IsEqualTo((int)5);
row.NullableInt32.IsEqualTo((int?)null);
row.NonNullableInt32Enum.IsEqualTo(IntEnum.Six);
row.NullableInt32Enum.IsEqualTo((IntEnum?)null);
}
public class WithInt16Values public class WithInt16Values
{ {
...@@ -1409,12 +1435,22 @@ public class WithInt16Values ...@@ -1409,12 +1435,22 @@ public class WithInt16Values
public short? NullableInt16 { get; set; } public short? NullableInt16 { get; set; }
public ShortEnum NonNullableInt16Enum { get; set; } public ShortEnum NonNullableInt16Enum { get; set; }
public ShortEnum? NullableInt16Enum { get; set; } public ShortEnum? NullableInt16Enum { get; set; }
} }
public enum ShortEnum : short public enum ShortEnum : short
{ {
Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6 Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6
} }
public class WithInt32Values
{
public int NonNullableInt32 { get; set; }
public int? NullableInt32 { get; set; }
public IntEnum NonNullableInt32Enum { get; set; }
public IntEnum? NullableInt32Enum { get; set; }
}
public enum IntEnum : int
{
Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6
}
public void TestTransactionCommit() public void TestTransactionCommit()
{ {
......
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