关于SQL SERVER bit类型数据为NULL导致EF Co
阅读本文可能需要3分钟
问题描述
今天遇到一个非常奇葩的问题,使用EF Core对一个旧表作查询,查询出来的实体集,可以看到有多少条数据,但却报错说这个实体集为null
而这个实体集的数目其实是符合我表中的数据,
当我继续运行的时候就会报以下错误,这个错误的提示很明显,就是说这个实体集是null,所以是没有对应的方法或属性使用。
所以我直接监视这个实体集,其实也是可以看到Results View
里面是没有数据的。
排查问题&解决历程
心里第一反应,“卧槽,又出bug了”,(哭丧脸.jpg)还是开始检查代码吧,但经过我一番检查,我是确信自己没有写错代码的,因为这个都只是最基础的EF查询。
心里第二反应,
没办法了只能出必杀技了,开始监控数据库,使用SQL SERVER自带的工具Profiler监控所有调用记录。如下图,可以看到整个记录中,只看到曾经有调用过查询数据总量的记录,其他的都没有,这样也符合VS的监控结果,实体集没有结果,但却有数据总量。
来到这一步,感觉就神了,感觉越来越接近真相,但却触不可及。
现在需要思考的是,为什么以下这行代码没有生效,不能生成SQL语句到数据库执行?
var basicData = BasicDataDtlDAL.Entities;
瞎搞了半天,因为在度娘中也找不出任何相似解决方案,所以也没啥办法了,只能逐个排查,我先使用相同的代码查询另一张表,发现是完全没有问题,那么也证实了一开始的想法,代码没有问题。
然后猜测可能就是数据问题,对比两张表的数据,大体相差不大,最大的不同可能就是目标表的有一个字段类型为bit
并且所有数据都是null,数据库的bit
类型对应C#的就是bool类型,理论上就是它的值应该是0或1,于是猜会不会是因为这个数据的问题,我就是尝试将这张表的bit类型这个字段的值全赋了0。
然后再重新执行了一次代码,见证奇迹的时候到了,如下图:
虽然代码正确运行了,但当时我的想法是,哈?怎么就正确了?
具体是什么原因我的知识有限也没找到相关的说明,不过我的猜测是sqlserver里bit类型是不能为null,如果直接使用ADO.NET直接使用SQL语句来查询应该是没问题的,因为我直接在数据库查询也是没问题的,但现在使用EF Core来查询的话,这个问题就暴露了。查询直接到不了数据库。这是一个巨坑啊!!
最后科普
这次的坑最主要的问题,应该是对SqlServer bit
类型的不了解,所以重新复习一下这个类型。
SqlServer的bit
类型是只0或者1,默认不输入值时为null,但是如果输入的值不是0或空字符串或“false”
这三种情况时,输入其他的值都会自动转换为1。
不过其实bit
对应的c#的bool
类型,那么最好还对它赋值0或1,不要留null,避免发生一些意想不到的情况。