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 ...@@ -50,7 +50,16 @@ public static partial class SqlMapperExtensions
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
var val = res[property.Name]; 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 ((IProxy)obj).IsDirty = false; //reset change tracking and return
...@@ -100,7 +109,16 @@ public static partial class SqlMapperExtensions ...@@ -100,7 +109,16 @@ public static partial class SqlMapperExtensions
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
var val = res[property.Name]; 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 ((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj); list.Add(obj);
......
...@@ -202,7 +202,16 @@ private static PropertyInfo GetSingleKey<T>(string method) ...@@ -202,7 +202,16 @@ private static PropertyInfo GetSingleKey<T>(string method)
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
var val = res[property.Name]; 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 ((IProxy)obj).IsDirty = false; //reset change tracking and return
...@@ -249,7 +258,16 @@ private static PropertyInfo GetSingleKey<T>(string method) ...@@ -249,7 +258,16 @@ private static PropertyInfo GetSingleKey<T>(string method)
foreach (var property in TypePropertiesCache(type)) foreach (var property in TypePropertiesCache(type))
{ {
var val = res[property.Name]; 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 ((IProxy)obj).IsDirty = false; //reset change tracking and return
list.Add(obj); list.Add(obj);
......
...@@ -355,6 +355,30 @@ public async Task GetAllAsync() ...@@ -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] [Fact]
public async Task InsertFieldWithReservedNameAsync() public async Task InsertFieldWithReservedNameAsync()
{ {
......
...@@ -53,6 +53,19 @@ public class User : IUser ...@@ -53,6 +53,19 @@ public class User : IUser
public int Age { get; set; } 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 class Person
{ {
public int Id { get; set; } public int Id { get; set; }
...@@ -543,6 +556,29 @@ public void GetAll() ...@@ -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] [Fact]
public void Transactions() public void Transactions()
{ {
......
...@@ -57,6 +57,8 @@ static SqlServerTestSuite() ...@@ -57,6 +57,8 @@ static SqlServerTestSuite()
connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);"); connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
dropTable("GenericType"); dropTable("GenericType");
connection.Execute("CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null);"); 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() ...@@ -106,6 +108,8 @@ static MySqlServerTestSuite()
connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);"); connection.Execute("CREATE TABLE ObjectZ (Id int not null, Name nvarchar(100) not null);");
dropTable("GenericType"); dropTable("GenericType");
connection.Execute("CREATE TABLE GenericType (Id nvarchar(100) not null, Name nvarchar(100) not null);"); 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) catch (MySqlException e)
...@@ -142,6 +146,7 @@ static SQLiteTestSuite() ...@@ -142,6 +146,7 @@ static SQLiteTestSuite()
connection.Execute("CREATE TABLE ObjectY (ObjectYId integer not null, Name nvarchar(100) not null) "); 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 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 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() ...@@ -173,6 +178,7 @@ static SqlCETestSuite()
connection.Execute(@"CREATE TABLE ObjectY (ObjectYId int not null, Name nvarchar(100) not null) "); 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 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 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"); 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