Let's assume that I have a class model that I would like to have non-default values in
public class MyModel()
{
public int PropertyOne { get; set; }
public int? PropertyTwo { get; set; }
public string PropertyThree { get; set; }
}
And let's say that I query for MyModel with this query
SELECT
NULL as PropertyOne,
NULL as PropertyTwo,
NULL as PropertyThree
If I map this to MyModel class, I will have PropertyOne = 0, PropertyTwo = null, PropertyThree = null.
By default Dapper will not call any setters if it encounters a DBNull value when reading, so PropertyOne has a default value of an int which is 0.
I don't want that, I would like to verify that I would always get a non-null value for PropertyOne from my query and I'd like to get an exception if the reader encounters a DBNull.
Let's say that I also don't want to have a null value for PropertyThree. Can I also achieve this check somehow with Dapper when mapping happens? And can I do this by using an attribute like in the model below?
public class MyModel()
{
public int PropertyOne { get; set; }
public int? PropertyTwo { get; set; }
[NotDBNull]
public string PropertyThree { get; set; }
}
So ideally what I want to achieve is use the above model and have the following logic:
Case 1: PropertyOne gets DBNull, but it's not nullable => throw an exception
Case 2: PropertyTwo gets DBNull, but it's nullable => all good
Case 3: PropertyThree gets DBNull, but is marked with [NotDBNull] attribute => throw an exception
Is there any way that I can achieve this with Dapper without using other forms of validation?
Dapper.AOT works (I hope! It is meant to) in the way you describe, for both value-types and reference-types (the latter if NRTs are enabled in the source).
It isn't possible for me to know from your code whether NRTs are enabled, but:
string
with NRTs enabled means "actively expect non-null"string?
with NRTs enabled means "allow null"string
without NRTs enabled means "allow null"int
means "actively expect non-null"int?
means "allow null"So: try Dapper.AOT and see how it goes! Depending on feedback we may add an attribute to soften this behaviour back to Dapper vanilla's null handling, but: what you describe is how we want things to work going forward.