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
When selecting a single column result for a custom type that is nullable, DBNull is passed to the type handler normally resulting in an InvalidCastException as the type handler is not expecting a null. Since the type handler can't return null either, it has no sensible way to handle the DBNull.
voidMain(){SqlMapper.AddTypeHandler(newMoneyTypeHandler());using(vardb=newSqlConnection("Server=(local); Integrated Security=SSPI")){db.Open();// Normal CLR types work fine when nullabledb.Query<int?>("SELECT 1").Single().Dump();db.Query<int?>("SELECT NULL").Single().Dump();// Nullable custom type works correctly when used as a propertydb.Query<Foo>("SELECT 1 AS Cost").Single().Dump();db.Query<Foo>("SELECT NULL AS Cost").Single().Dump();// Fails when used as a single column scalar resultdb.Query<Money?>("SELECT 1").Single().Dump();db.Query<Money?>("SELECT NULL").Single().Dump();}}publicclassMoneyTypeHandler:SqlMapper.TypeHandler<Money>{publicoverridevoidSetValue(IDbDataParameterp,Moneyvalue){p.DbType=DbType.Int32;p.Value=value.Value;}publicoverrideMoneyParse(objectobj){if(objisDBNull){thrownewInvalidCastException("Expected type int, got type DBNull");}returnnewMoney((int)obj);}}publicstructMoney{privatereadonlyintvalue;publicMoney(intvalue){this.value=value;}publicintValue{get{returnvalue;}}}publicclassFoo{publicMoney?Cost{get;set;}}
The text was updated successfully, but these errors were encountered:
The obvious fix would be to add a check for DBNull, but that would be a breaking change to any one who expects and handles DBNull already (such as translating to/from a sentinel value).
Though I'm not sure how many people would run in to that problem since they can't apply the reverse transformation because SetValue does check for DBNull.
Thinking about it, I'm inclined to say that no one should be relying on getting a DBNull there since it only occurs in one scenario and that is when you're querying a nullable struct directly. In most other cases (i.e. when it's a property of another type) the type handler never sees the null because the standard property handling filters it out.
When selecting a single column result for a custom type that is nullable, DBNull is passed to the type handler normally resulting in an
InvalidCastException
as the type handler is not expecting a null. Since the type handler can't return null either, it has no sensible way to handle the DBNull.The text was updated successfully, but these errors were encountered: