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
Then I have a POCO class with all those columns, but the boolean columns are correctly defined as bool type.
If I just query SELECT * FROM [tab] it obviously crashes, because Dapper can't convert "YES" to true.
I know that I can query by enumerating ALL columns and using formulas to convert the ones which require conversion:
cn.Query<POCO>(@" SELECT CAST(CASE WHEN [boolcol]='YES' THEN 1 ELSE 0 END AS BIT) as [boolcol], -- it works col1, col2, etc.. many many columns here FROM [tab]")
However, since there are many columns I'd like to use * to get all columns and only specify exceptional conversions for the columns which won't be automatically converted by Dapper, but this fails:
cn.Query<POCO>(@" SELECT CAST(CASE WHEN [boolcol]='YES' THEN 1 ELSE 0 END AS BIT) as [boolcol], * -- this fails because boolcol will ALSO be returned here, and will be converted and crash FROM [tab]")
When the second occurrence of boolcol is returned (the real column, not the formula with alias) it will also try to convert to bool, and it will crash.
I know that the table design is ugly, and I know that I could use getters/setters in my POCO to translate the string to boolean, but it's all legacy (used in multiple places and spread across multiple forks) so I'm trying to handle everything in the query.
First question: Why does Dapper try to convert ALL occurrences with the same column name?
I mean: If I add two occurrences of [boolcol] in my query I would expect that only the first occurrence is mapped (and therefore converted) so that my conversion in the last SQL Query above would work and the second occurrence of [boolcol] would be ignored - but what happens is that ALL occurrences are converted, which make invalid conversions crash (and if they didn't crash the winning value would be the last occurrence, which sounds counterintuitive).
If I can't do that using query, my second approach to this problem would be registering a TypeHandler to convert the string to boolean:
publicclassLenientBooleanHandler:SqlMapper.TypeHandler<bool>{publicoverrideboolParse(objectvalue){if(valueisstring){return((string)value=="YES");}// Here: How can I just rely on existing Dapper conversions // to fallback on the regular 1==true, "true"==true, etc?if(valueisint){return((int)value==1);}if(valueisdecimal){return((decimal)value==1);}return(bool)value;}publicoverridevoidSetValue(IDbDataParameterparameter,boolvalue){// will all booleans passed to the database be converted through here?// even if they are NOT to be converted as strings? // what should I put here to keep the default out-of-the-box behavior?// I don't want to break primitive types!}}
Second question: In the TypeHandler above can I just test for those exceptional conversions and rely on regular Dapper conversions for 1, 0, "true", etc? Mostly for SetValue - what should I put in SetValue so that I don't break behavior in other places?
I'm very scared of replacing bool TypeHandler, and I'm aware that TypeHandlers have some issues with primitive types (607 and 433) - that's why the query-only approach would be my first option.
The text was updated successfully, but these errors were encountered:
Drizin
changed the title
TypeHandler with fallback behavior / Query with Multiple columns with same name
Query with Multiple columns with same name / How to change TypeHandler for Primitive Types
Dec 23, 2020
I have a table with tens of columns but the boolean columns are stored as varchar "YES" / "NO":
Then I have a POCO class with all those columns, but the boolean columns are correctly defined as
bool
type.If I just query
SELECT * FROM [tab]
it obviously crashes, because Dapper can't convert "YES" to true.I know that I can query by enumerating ALL columns and using formulas to convert the ones which require conversion:
However, since there are many columns I'd like to use
*
to get all columns and only specify exceptional conversions for the columns which won't be automatically converted by Dapper, but this fails:When the second occurrence of
boolcol
is returned (the real column, not the formula with alias) it will also try to convert to bool, and it will crash.I know that the table design is ugly, and I know that I could use getters/setters in my POCO to translate the string to boolean, but it's all legacy (used in multiple places and spread across multiple forks) so I'm trying to handle everything in the query.
First question: Why does Dapper try to convert ALL occurrences with the same column name?
I mean: If I add two occurrences of
[boolcol]
in my query I would expect that only the first occurrence is mapped (and therefore converted) so that my conversion in the last SQL Query above would work and the second occurrence of[boolcol]
would be ignored - but what happens is that ALL occurrences are converted, which make invalid conversions crash (and if they didn't crash the winning value would be the last occurrence, which sounds counterintuitive).If I can't do that using query, my second approach to this problem would be registering a TypeHandler to convert the string to boolean:
Second question: In the TypeHandler above can I just test for those exceptional conversions and rely on regular Dapper conversions for 1, 0, "true", etc? Mostly for SetValue - what should I put in SetValue so that I don't break behavior in other places?
I'm very scared of replacing bool TypeHandler, and I'm aware that TypeHandlers have some issues with primitive types (607 and 433) - that's why the query-only approach would be my first option.
The text was updated successfully, but these errors were encountered: