帮朋友分担一些项目任务时遇到的一个问题:sql 语句查出的结果,和 ORM 读取到的值居然不一致,一度让我怀疑是哪里序列化出问题了。
由于心想着赶紧整完吃饭,也没怎么看数据库表结构,一时没想到是类型的问题,调试了半天才注意到了字段的类型是tinyint(1)
,瞬间想给自己几巴掌......
不过之前只记得 tinyint(1)
在 mysql 中是作为 bool 类型(非零值为 true)的,能马上联想到是类型错误导致的,只是具体原因并不清楚。
在查阅了官方的一些资料后发现这并不是一个bug,但也没有具体解释为何这么设计,我猜是当时的历史遗留问题,也可能是设计缺陷,不过可以通过连接字符串添加 Treat Tiny As Boolean=false
的配置方式取消隐式转换。
引用原文链接:https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html#idm46095360188160
These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true:
mysql> SELECT IF(0, 'true', 'false'); +------------------------+ | IF(0, 'true', 'false') | +------------------------+ | false | +------------------------+mysql> SELECT IF(1, 'true', 'false'); +------------------------+ | IF(1, 'true', 'false') | +------------------------+ | true | +------------------------+mysql> SELECT IF(2, 'true', 'false'); +------------------------+ | IF(2, 'true', 'false') | +------------------------+ | true | +------------------------+
引用原文链接:https://bugs.mysql.com/bug.php?id=67381
[25 Oct 2012 20:36] Baskin Tapkan
Description:
TinyInt(1) data type for a column is translated as a Boolean in .NET POCO class and ADO.NET Entity frameworkHow to repeat:
- Create a table with a TINYINT(1) column type
- Using the MySQL.Data and MySQL.Data.Entity NuGet packages, create a ADO.NET Entity Data model
- Observe that the data type for the TINYINT(1) is now shown as "Boolean"
[29 Jan 2013 23:33] Fernando Gonzalez.Sanchez
Thanks for your report,This is not actually a bug, you can add to your connection string
"Treat Tiny As Boolean=false;"and now the tinyint will be interpreted like a type sbyte in C#.