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

记录一次.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’.

两个解决方案

(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,个人理解,如有错误,请一定告知,学习进步!

你可能感兴趣的:(System.InvalidCastException: Unable to cast object of type 'System.Boolean' to type 'System.SByte'.)