System.InvalidCastException: Unable to cast object of type ‘System.Boolean‘ to type ‘System.SByte‘.

本文介绍了在使用EF Core查询MySQL数据库时遇到的`System.InvalidCastException`异常,该异常源于tinyint(1)字段被转换为Boolean再尝试转换为SByte。提供了两种解决方案:一是修改映射关系,指定tinyint(1)对应的数据库类型为bit(1);二是设置MySQL连接字符串中的`TreatTinyAsBoolean=false`,避免数据转换。选择任一方案即可解决问题。

记录一次.NET CORE下的异常.

异常信息如下:
System.InvalidCastException: Unable to cast object of type ‘System.Boolean’ to type ‘System.SByte’.

通常发生在EF Core查询数据时使用Mysql ,同时表中含有类型为tinyint(1)列的情况下。

EF Core将tinyint(int) 映射为System.SByte类型(按理说应该映射成System.Byte,实际上就是System.Byte,也不知道为啥处理的时候使用SByte,学艺不精,有知道的大佬请一定告知,谢谢!),当我们从Mysql拿数据时,Mysql会将tinyint(int)转换成Boolean类型返回,EF Core拿到这个数据时,会按照映射关系将其转换成System.SByte,然后就会出现以下异常。
System.InvalidCastException: Unable to cast object of type ‘System.Boolean’ to type ‘System.SByte’.

Mysql 的 tinyint 类型可以设置为有符号,也可设置为无符号,所以映射成System.SByte没有问题。

两个解决方案

(1)修改映射关系,在代码中指定实体类中Boolean类型属性的对应数据库类型为bit(1),这样就会形成一个bit(1)<==>boolean的映射。

映射是数据库类型和.NET类型之间的映射,如果你没有指定实体中属性对应的数据库类型,那么EFCore会根据数据库架构,推断出每个属性对应的数据库类型,然后在这个数据库类型的基础上生成和对应.NET类型的映射,之后EFCore处理数据,就只会参照这个映射关系,不会去管你数据库里实际上存的是什么类型,在EFCore眼里,你的数据库类型就是映射关系里的那个类型,会按照那个类型去找对应的.NET类型,然后转换。

举个例子

    [MaxLength(1)]
    [Required]
    [Column("BoolFlag",TypeName = "bit(1)")]
    public bool BoolFlag { get; set; }

在数据库里,我存的是tinyint(1)类型,但是我只要在这里指定了数据库类型,那么EFCore只会根据这个去找对应的.NET类型,bit(1)的对应.NET类型就是Boolean类型,所以接收Mysql传来的数据,就会将它转换成Boolean,先前说过Mysql会将tinyint(int)转换成Boolean类型返回,所以就不存在转换失败的问题。

(2)在MySQL连接字符串中添加参数"TreatTinyAsBoolean=false",这样Mysql在处理tinyint(1)类型数据时,会不做转换直接返回,返回的数据是用一个字节存放的0或1,EF Core将对应数据转换成SByte。

从数据库中将数据拉入内存时的转换应该都是隐式的。

从内存中的原始数据到实体类的对象集合,应该存在一个通过构造函数构造或者类似于强制转换的处理,将内存中原始数据的类型转换成实体类指定的类型。

两种方案选择一种即可。

未系统学过.NET,个人理解,如有错误,请一定告知,学习进步!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值