I am working on a code generator and trying to map CLR types to SQL types.
Example:
using System.Data;
using System.Data.SqlTypes;
var dictionaryCtsToSql = new Dictionary<Type, SqlDbType>();
dictionaryCtsToSql.Add(typeof(Boolean), SqlDbType.Bit);
dictionaryCtsToSql.Add(typeof(Boolean?), SqlDbType.Bit);
...
dictionaryCtsToSql.Add(typeof(Byte), SqlDbType.TinyInt);
dictionaryCtsToSql.Add(typeof(Byte?), SqlDbType.TinyInt);
dictionaryCtsToSql.Add(typeof(Int32), SqlDbType.Int);
dictionaryCtsToSql.Add(typeof(Int32?), SqlDbType.Int);
dictionaryCtsToSql.Add(typeof(UInt32), SqlDbType.BigInt);
dictionaryCtsToSql.Add(typeof(UInt32?), SqlDbType.BigInt);
dictionaryCtsToSql.Add(typeof(Single), SqlDbType.Real);
dictionaryCtsToSql.Add(typeof(Single?), SqlDbType.Real);
...
dictionaryCtsToSql.Add(typeof(DateTime), SqlDbType.DateTime2);
dictionaryCtsToSql.Add(typeof(DateTime?), SqlDbType.DateTime2);
dictionaryCtsToSql.Add(typeof(DateTimeOffset), SqlDbType.DateTimeOffset);
dictionaryCtsToSql.Add(typeof(DateTimeOffset?), SqlDbType.DateTimeOffset);
...
This works fine for primitives / value-types but not on a nullable string as follows:
dictionaryCtsToSql.Add(typeof(String), SqlDbType.NVarChar);
dictionaryCtsToSql.Add(typeof(String?), SqlDbType.NVarChar); // Error.
Now, I completely understand WHY this would cause an error on reference types, but I am targeting .NET 8 that uses C# 12, and the project has its nullability setting enabled:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
So, consider the following class:
using System.Data;
using System.Data.SqlTypes;
public class Entity
{
public long Id { get; set; }
public string NameGiven { get; set; } = string.Empty;
public string? NameMiddle { get; set; }
public string NameFamily { get; set; } = string.Empty;
public DateTime DateTimeFrom { get; set; } = SqlDateTime.MinValue.Value;
public DateTime? DateTimeUntil { get; set; }
}
I checked the reflected property and it appears the Type
is still String
with an added NullableAttribute
:
Value types, on the other hand, are wrapped in another struct Nullable<TValueType>
. This means that string?
is not a new type at all as opposed to int?
.
So, the question against this long-winded explanation is: I would very much like to use the existing dictionary Dictionary<Type, SqlDbType>
if possible, without having to check for nullability attributes in code. Is this possible? If not, shouldn't it be?
I suppose I am a bit sad to know that nullable reference types seem to be designed for code-quality rather than runtime functionality.
"I suppose I am a bit sad to know that nullable reference types seem to be designed for code-quality rather than runtime functionality" - To your disappointment, this is true.