Commit 07fe543f authored by Jase's avatar Jase Committed by Nick Craver

Change to GetAll to allow the usage of a nullable type in T when T is an interface… #933 (#936)

* Change to GetAll to allow the usage of a nullable type in T when T is an interface.

* Change to GetAll to allow the usage of a nullable type in T when T is an interface: further change to check if val == null and if so then don't try to assign it as a property value.

* Change to Get to allow the usage of a nullable type in T when T is an interface. (effectively the same change as the previous change to GetAll.)

* Change to GetAsync and GetAllAsync to allow the usage of a nullable type in T when T is  an interface.

* Added in UserWithNullableDob and IUserWithNullableDob.

Added in tests for GetAndGetAllWithNullableValues and  GetAsyncAndGetAllAsyncWithNullableValues.

* Added in .ConfigureAwait(false) in the GetAsync Test.
Added comment to identify which issue the test relates to.

* Added NullableDates tables to the test databases.
Adjusted variable names in GetAndGetAllWithNullableValues and GetAsyncAndGetAllAsyncWithNullableValues.

* Changed IUserWithNullableDob to INullableDate.
parent 671419c3
......@@ -50,7 +50,16 @@ public static partial class SqlMapperExtensions
foreach (var property in TypePropertiesCache(type))
{
var val = res[property.Name];
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
}
else
{
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
}
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
......@@ -100,7 +109,16 @@ public static partial class SqlMapperExtensions
foreach (var property in TypePropertiesCache(type))
{
var val = res[property.Name];
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
}
else
{
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
}
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
......
......@@ -202,7 +202,16 @@ private static PropertyInfo GetSingleKey<T>(string method)
foreach (var property in TypePropertiesCache(type))
{
var val = res[property.Name];
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
}
else
{
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
}
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
......@@ -249,7 +258,16 @@ private static PropertyInfo GetSingleKey<T>(string method)
foreach (var property in TypePropertiesCache(type))
{
var val = res[property.Name];
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
}
else
{
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null);
}
}
((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj);
......
......@@ -355,6 +355,30 @@ public async Task GetAllAsync()
}
}
/// <summary>
/// Test for issue #933
/// </summary>
[Fact]
public async void GetAsyncAndGetAllAsyncWithNullableValues()
{
using (var connection = GetOpenConnection())
{
var id1 = connection.Insert(new NullableDate { DateValue = new DateTime(2011, 07, 14) });
var id2 = connection.Insert(new NullableDate { DateValue = null });
var value1 = await connection.GetAsync<INullableDate>(id1).ConfigureAwait(false);
Assert.Equal(new DateTime(2011, 07, 14), value1.DateValue.Value);
var value2 = await connection.GetAsync<INullableDate>(id2).ConfigureAwait(false);
Assert.True(value2.DateValue == null);
var value3 = await connection.GetAllAsync<INullableDate>().ConfigureAwait(false);
var valuesList = value3.ToList();
Assert.Equal(new DateTime(2011, 07, 14), valuesList[0].DateValue.Value);
Assert.True(valuesList[1].DateValue == null);
}
}
[Fact]
public async Task InsertFieldWithReservedNameAsync()
{
......
......@@ -53,6 +53,19 @@ public class User : IUser
public int Age { get; set; }
}
public interface INullableDate
{
[Key]
int Id { get; set; }
DateTime? DateValue { get; set; }
}
public class NullableDate : INullableDate
{
public int Id { get; set; }
public DateTime? DateValue { get; set; }
}
public class Person
{
public int Id { get; set; }
......@@ -543,6 +556,29 @@ public void GetAll()
}
}
/// <summary>
/// Test for issue #933
/// </summary>
[Fact]
public void GetAndGetAllWithNullableValues()
{
using (var connection = GetOpenConnection())
{
var id1 = connection.Insert(new NullableDate { DateValue = new DateTime(2011, 07, 14) });
var id2 = connection.Insert(new NullableDate { DateValue = null });
var value1 = connection.Get<INullableDate>(id1);
Assert.Equal(new DateTime(2011, 07, 14), value1.DateValue.Value);
var value2 = connection.Get<INullableDate>(id2);
Assert.True(value2.DateValue == null);
var value3 = connection.GetAll<INullableDate>().ToList();
Assert.Equal(new DateTime(2011, 07, 14), value3[0].DateValue.Value);
Assert.True(value3[1].DateValue == null);
}
}
[Fact]
public void Transactions()
{
......
......@@ -57,6 +57,8 @@ static SqlServerTestSuite()
connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
dropTable("GenericType");
connection.Execute("CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null);");
dropTable("NullableDates");
connection.Execute("CREATE TABLE NullableDates (Id int IDENTITY(1,1) not null, DateValue DateTime null);");
}
}
}
......@@ -106,6 +108,8 @@ static MySqlServerTestSuite()
connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
dropTable("GenericType");
connection.Execute("CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null);");
dropTable("NullableDates");
connection.Execute("CREATE TABLE NullableDates (Id int not null AUTO_INCREMENT PRIMARY KEY, DateValue DateTime);");
}
}
catch (MySqlException e)
......@@ -142,6 +146,7 @@ static SQLiteTestSuite()
connection.Execute("CREATE TABLE ObjectY (ObjectYId integer not null, Name nvarchar(100) not null) ");
connection.Execute("CREATE TABLE ObjectZ (Id integer not null, Name nvarchar(100) not null) ");
connection.Execute("CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null) ");
connection.Execute("CREATE TABLE NullableDates (Id integer primary key autoincrement not null, DateValue DateTime) ");
}
}
}
......@@ -173,6 +178,7 @@ static SqlCETestSuite()
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId int not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null) ");
connection.Execute(@"CREATE TABLE NullableDates (Id int IDENTITY(1,1) not null, DateValue DateTime null) ");
}
Console.WriteLine("Created database");
}
......
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