Skip to content

Commit

Permalink
Change to GetAll to allow the usage of a nullable type in T when T is…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
JaseRandall authored and NickCraver committed Mar 9, 2018
1 parent 671419c commit 07fe543
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 4 deletions.
22 changes: 20 additions & 2 deletions Dapper.Contrib/SqlMapperExtensions.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,16 @@ public static async Task<T> GetAsync<T>(this IDbConnection connection, dynamic i
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
Expand Down Expand Up @@ -100,7 +109,16 @@ private static async Task<IEnumerable<T>> GetAllAsyncImpl<T>(IDbConnection conne
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);
Expand Down
22 changes: 20 additions & 2 deletions Dapper.Contrib/SqlMapperExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,16 @@ public static T Get<T>(this IDbConnection connection, dynamic id, IDbTransaction
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
Expand Down Expand Up @@ -249,7 +258,16 @@ public static IEnumerable<T> GetAll<T>(this IDbConnection connection, IDbTransac
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);
Expand Down
24 changes: 24 additions & 0 deletions Dapper.Tests.Contrib/TestSuite.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
36 changes: 36 additions & 0 deletions Dapper.Tests.Contrib/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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()
{
Expand Down
6 changes: 6 additions & 0 deletions Dapper.Tests.Contrib/TestSuites.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);");
}
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) ");
}
}
}
Expand Down Expand Up @@ -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");
}
Expand Down

0 comments on commit 07fe543

Please sign in to comment.