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)
return GetDynamicDeserializer(reader, startBound, length, returnNullIfFirstMissing);
}
#endif
if (!(typeMap.ContainsKey(type) || type.FullName == LinqBinary))
Type underlyingType = null;
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 GetStructDeserializer(type, startBound);
return GetStructDeserializer(type, underlyingType ?? type, startBound);
}
#if !CSHARP30
......@@ -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!)
#pragma warning disable 618
......@@ -1412,6 +1413,15 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction transaction,
return r => Activator.CreateInstance(type, r.GetValue(index));
}
#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 =>
{
var val = r.GetValue(index);
......
......@@ -1378,10 +1378,9 @@ public void TestInt16Usage()
connection.Query<short?>("select cast(42 as smallint)").Single().IsEqualTo((short?)42);
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(null as smallint)").Single().IsEqualTo((ShortEnum?)null);
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);
var row =
connection.Query<WithInt16Values>(
......@@ -1401,7 +1400,34 @@ public void TestInt16Usage()
row.NonNullableInt16Enum.IsEqualTo(ShortEnum.Six);
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
{
......@@ -1409,12 +1435,22 @@ public class WithInt16Values
public short? NullableInt16 { get; set; }
public ShortEnum NonNullableInt16Enum { get; set; }
public ShortEnum? NullableInt16Enum { get; set; }
}
public enum ShortEnum : short
{
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()
{
......
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