Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
Fix matching nullable properties in convetions
Browse files Browse the repository at this point in the history
Resolves #82
  • Loading branch information
henkmollema committed Mar 28, 2019
1 parent eddd12d commit 837332b
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
15 changes: 12 additions & 3 deletions src/Dapper.FluentMap/Conventions/Convention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,18 @@ protected PropertyConventionConfiguration Properties()
/// <returns>A configuration object for the convention.</returns>
protected PropertyConventionConfiguration Properties<T>()
{
// Get the underlying type for a nullale type. (int? -> int)
var underlyingType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
var config = new PropertyConventionConfiguration().Where(p => p.PropertyType == underlyingType);
var type = typeof(T);
PropertyConventionConfiguration config;
if (Nullable.GetUnderlyingType(type) != null)
{
// Convention defined for nullable type, match nullable properties
config = new PropertyConventionConfiguration().Where(p => p.PropertyType == type);
}
else
{
// Convention defined for non-nullable types, match both nullabel and non-nullable properties
config = new PropertyConventionConfiguration().Where(p => (Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType) == type);
}
ConventionConfigurations.Add(config);

return config;
Expand Down
53 changes: 53 additions & 0 deletions test/Dapper.FluentMap.Tests/ConventionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,41 @@ public void DerivedProperties()
Assert.Equal(typeof(DerivedTestEntity).GetProperty(nameof(TestEntity.Id)), colId.Property);
}

[Fact]
public void NullableProperties()
{
// Arrange
FluentMapper.Initialize(c => c.AddConvention<NullableConvention>().ForEntity<TestEntity>());
var typeMap = SqlMapper.GetTypeMap(typeof(TestEntity));

// Act
var colValue = typeMap.GetMember("intId");
var colValueNotNull = typeMap.GetMember("intOtherId");

//Assert
Assert.NotNull(colValue);
Assert.NotNull(colValueNotNull);
Assert.Equal(typeof(TestEntity).GetProperty(nameof(TestEntity.Id)), colValue.Property);
Assert.Equal(typeof(TestEntity).GetProperty(nameof(TestEntity.OtherId)), colValueNotNull.Property);
}

[Fact]
public void ExplicitNullableProperties()
{
// Arrange
FluentMapper.Initialize(c => c.AddConvention<ExplicitNullableConvention>().ForEntity<TestEntityWithNullable>());
var typeMap = SqlMapper.GetTypeMap(typeof(TestEntityWithNullable));

// Act
var colValue = typeMap.GetMember("decValue");
var colValueNotNull = typeMap.GetMember("decValueNotNull");

//Assert
Assert.NotNull(colValue);
Assert.Null(colValueNotNull);
Assert.Equal(typeof(TestEntityWithNullable).GetProperty(nameof(TestEntityWithNullable.Value)), colValue.Property);
}

[Fact]
public void TwoEntitiesWithSamePropertyName()
{
Expand Down Expand Up @@ -84,6 +119,24 @@ public TestConvention()
}
}

private class NullableConvention : Convention
{
public NullableConvention()
{
Properties<int>()
.Configure(c => c.HasPrefix("int"));
}
}

private class ExplicitNullableConvention : Convention
{
public ExplicitNullableConvention()
{
Properties<decimal?>()
.Configure(c => c.HasPrefix("dec"));
}
}

private class DerivedConvention : Convention
{
public DerivedConvention()
Expand Down
2 changes: 2 additions & 0 deletions test/Dapper.FluentMap.Tests/TestEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namespace Dapper.FluentMap.Tests
public class TestEntity
{
public int Id { get; set; }

public int? OtherId { get; set; }
}

public class TestEntityWithNullable
Expand Down

0 comments on commit 837332b

Please sign in to comment.