从MySQL读取Boolean字段时遇InvalidCastException异常求助
这个坑我之前踩过!MySQL Connector/NET对数据库布尔类型的映射逻辑有点“反直觉”——尽管你在数据库里把enabled定义为boolean default false,但它实际返回给DataTable的是Byte类型的值(0代表false,1代表true),而不是C#原生的bool类型,这就是直接用row.Field<Boolean>("enabled")抛出InvalidCastException的原因。
给你两种靠谱的解决方案:
方案1:手动转换Byte到Boolean
直接读取字段的Byte值,再转换成bool,代码修改如下:
List<Account> accounts = dt.AsEnumerable().Select(row => new Account { name = row.Field<string>("user"), enabled = row.Field<byte>("enabled") == 1 // 0→false,1→true }).ToList();
或者用Convert.ToBoolean简化转换,它能自动识别Byte类型的0/1:
enabled = Convert.ToBoolean(row["enabled"])
方案2:修改连接字符串,让驱动自动映射布尔类型
这是一劳永逸的方法,在你的连接字符串里添加TreatTinyAsBoolean=true配置项,告诉MySQL驱动把数据库的boolean(本质是tinyint(1))直接映射为C#的bool类型:
string connString = "SERVER=localhost;DATABASE=accs;UID=root;PASSWORD=root;TreatTinyAsBoolean=true;";
修改后,你原来的代码row.Field<Boolean>("enabled")就能正常工作了,不需要再手动转换。
为什么你之前的尝试报错?
你用"1".Equals(row.Field("enabled"))或者row.Field("enabled")==1报错,是因为row.Field必须指定泛型(DataRowExtensions的Field方法没有无泛型重载),你实际应该是用了row["enabled"],它返回的是object类型:直接和字符串"1"比较会因为类型不匹配失败;和数字1比较的话,若不先把object转成Byte,也会因类型不一致抛出异常。
内容的提问来源于stack exchange,提问作者webpersistence

