Skip to content

Commit e0fb46f

Browse files
authored
fix: Deserialize parseable POCO properties to the nullable underlying type (influxdata#251)
1 parent 65a2b8e commit e0fb46f

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
### Features
44
1. [#239](https://github.com/influxdata/influxdb-client-csharp/pull/239): Add support for Asynchronous queries [LINQ]
55
1. [#240](https://github.com/influxdata/influxdb-client-csharp/pull/240): Add IsMeasurement option to Column attribute for dynamic measurement names in POCO classes
6-
1. [#246](https://github.com/influxdata/influxdb-client-csharp/pull/246): Add support for deserialization of POCO column property types with a "Parse" method, such as Guid
6+
1. [#246](https://github.com/influxdata/influxdb-client-csharp/pull/246), [#251](https://github.com/influxdata/influxdb-client-csharp/pull/251): Add support for deserialization of POCO column property types with a "Parse" method, such as Guid
77

88
## 3.0.0 [2021-09-17]
99

Client.Core/Flux/Internal/FluxResultMapper.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,12 @@ private void SetFieldValue<T>(T poco, PropertyInfo property, object value)
153153
return;
154154
}
155155

156+
// Nullable types cannot be used in type conversion, but we can use Nullable.GetUnderlyingType()
157+
// to determine whether the type is nullable and convert to the underlying type instead
158+
var targetType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
159+
156160
// Handle parseables
157-
var parseMethod = GetParseMethod(propertyType, valueType);
161+
var parseMethod = GetParseMethod(targetType, valueType);
158162
if (parseMethod != null)
159163
{
160164
var parsed = parseMethod.Invoke(null, new[] { value });
@@ -165,9 +169,6 @@ private void SetFieldValue<T>(T poco, PropertyInfo property, object value)
165169
// Handle convertibles
166170
if (value is IConvertible)
167171
{
168-
// Nullable types cannot be used in type conversion, but we can use Nullable.GetUnderlyingType()
169-
// to determine whether the type is nullable and convert to the underlying type instead
170-
var targetType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
171172
property.SetValue(poco, Convert.ChangeType(value, targetType));
172173
return;
173174
}
@@ -209,8 +210,10 @@ private MethodInfo GetParseMethod(Type parserType, Type valueType)
209210
}
210211

211212
var paramType = parameters[0].ParameterType;
212-
paramType = Nullable.GetUnderlyingType(paramType) ?? paramType;
213+
if (valueType == paramType)
214+
return true;
213215

216+
paramType = Nullable.GetUnderlyingType(paramType) ?? paramType;
214217
return valueType == paramType;
215218
})
216219
.FirstOrDefault();

Client.Legacy.Test/FluxResultMapperTest.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ public void ParseableProperty()
118118
Assert.AreEqual(expectedValue, poco.Value);
119119
Assert.AreEqual(expectedTime, Instant.FromDateTimeUtc(poco.Timestamp));
120120
}
121+
122+
[TestCase(null)]
123+
[TestCase("e11351a6-62ec-468b-8b64-e1414aca2c7d")]
124+
public void NullableParseableProperty(string guid)
125+
{
126+
string expectedTag = "test";
127+
Guid? expectedValue = guid == null ? (Guid?)null : Guid.Parse(guid);
128+
Instant expectedTime = Instant.FromDateTimeUtc(DateTime.UtcNow);
129+
130+
var record = new FluxRecord(0);
131+
record.Values["tag"] = expectedTag;
132+
record.Values["value"] = guid;
133+
record.Values["_time"] = expectedTime;
134+
135+
var poco = _parser.ToPoco<NullableParseablePoco>(record);
136+
137+
Assert.AreEqual(expectedTag, poco.Tag);
138+
Assert.AreEqual(expectedValue, poco.Value);
139+
Assert.AreEqual(expectedTime, Instant.FromDateTimeUtc(poco.Timestamp));
140+
}
121141

122142
[Measurement("poco")]
123143
private class ParseablePoco
@@ -131,5 +151,18 @@ private class ParseablePoco
131151
[Column(IsTimestamp = true)]
132152
public DateTime Timestamp { get; set; }
133153
}
154+
155+
[Measurement("poco")]
156+
private class NullableParseablePoco
157+
{
158+
[Column("tag", IsTag = true)]
159+
public string Tag { get; set; }
160+
161+
[Column("value")]
162+
public Guid? Value { get; set; }
163+
164+
[Column(IsTimestamp = true)]
165+
public DateTime Timestamp { get; set; }
166+
}
134167
}
135-
}
168+
}

0 commit comments

Comments
 (0)