You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the following case, option SqlMapper.Settings.ApplyNullValues is not respected, null-values are not assigned:
I have a DTO (PersonDto) with some properties (Id, GivenName, MiddleName, Surname, Picture). The Id is of data type Int32, the other properties are Settable<T>:
public class PersonDto {
public int Id { get; set; }
public Settable<string> GivenName { get; set; }
public Settable<string?> MiddleName { get; set; }
public Settable<string> Surname { get; set; }
public Settable<byte[]?> Picture { get; set; }
}
Settable<T> is a structure (value type) that allows to distinguish whether a value was assigned null or was not initialized. Imagine now a data access method that returns a list of PersonDto and that has a Boolean parameter IncludePicture that is false by default and that adjusts the SQL query accordingly to avoid loading expensive property Picture when it is not needed. When the consumer of this method now accidentally accesses uninitialized property Picture, an InvalidOperationException is thrown. Unfortunately that is now also the case for the MiddleName that should have been initialized with null and wasn't. Here the test method:
[TestMethod]
public void Null_Value_Is_Not_Applied_Although_ApplyNullValues_Flag_Is_Set() {
LocalDB localDB = LocalDBManager.CreateLocalDB("SQL-Scripts"); //Creates a new database on LocalDB-SQLServer
IDbConnection dbConnection = localDB.DatabaseConnection;
dbConnection.EnsureSettableConvertersLoaded(); //Sets ApplyNullValues and registers the converters to Settable<T>
Assert.IsTrue(SqlMapper.Settings.ApplyNullValues);
PersonDto actual = dbConnection.QuerySingle<PersonDto>("SELECT Id, GivenName, MiddleName, Surname FROM Person WHERE Id = 3;");
Assert.IsTrue(SqlMapper.Settings.ApplyNullValues);
Assert.AreEqual("Kerry", actual.GivenName);
Assert.AreEqual("Norton", actual.Surname);
Assert.IsNull(actual.MiddleName.Value); // <--- Fails (null was not assigned!)
Assert.ThrowsException<InvalidOperationException>(() => actual.Picture.Value); //Works as expected, throws an exception because the value was not initialized.
}
And here the prove that the bug is not in Settable<T>:
[TestMethod]
public void Settable_Works_As_Expected() {
PersonDto actual = new PersonDto();
actual.GivenName = "Kerry";
actual.MiddleName = null;
actual.Surname = "Norton";
Assert.AreEqual("Kerry", actual.GivenName);
Assert.AreEqual("Norton", actual.Surname);
Assert.IsNull(actual.MiddleName.Value); //Works, null was assigned.
Assert.ThrowsException<InvalidOperationException>(() => actual.Picture.Value); //Works as expected, throws an exception because the value was not initialized.
}
Here the complete test project (Visual Studio 2022 solution) including database initialization on test execution (using LocalDB): BugReport.zip
The text was updated successfully, but these errors were encountered:
In the following case, option
SqlMapper.Settings.ApplyNullValues
is not respected,null
-values are not assigned:I have a DTO (
PersonDto
) with some properties (Id
,GivenName
,MiddleName
,Surname
,Picture
). TheId
is of data typeInt32
, the other properties areSettable<T>
:Settable<T>
is a structure (value type) that allows to distinguish whether a value was assignednull
or was not initialized. Imagine now a data access method that returns a list ofPersonDto
and that has aBoolean
parameterIncludePicture
that isfalse
by default and that adjusts the SQL query accordingly to avoid loading expensive propertyPicture
when it is not needed. When the consumer of this method now accidentally accesses uninitialized propertyPicture
, anInvalidOperationException
is thrown. Unfortunately that is now also the case for theMiddleName
that should have been initialized withnull
and wasn't. Here the test method:And here the prove that the bug is not in
Settable<T>
:Here the complete test project (Visual Studio 2022 solution) including database initialization on test execution (using LocalDB):
BugReport.zip
The text was updated successfully, but these errors were encountered: