前言目前的项目,在操作数据库的时候,喜欢使用ORM框架,其中EF用的比较多;EF的封装确实让小伙伴们专注于业务逻辑就足够了,而不必过多关注操作数据库的具体细节。但是在某些场景下,你会选择执行SQL语句,比如一些复杂的插入或者报表查询。其实不管用什么方法执行SQL语句,都需要防止SQL注入,所以才有了下面的讨论。正文1.首先来到EFCore执行SQL演示1.1准备一个EFCore项目关于EFCore在项目中的使用,之前分享过一篇很详细的文章,这里不再赘述。详情请看这里《跟我一起学.NetCore之EF Core 实战入门,一看就会》。1.2执行原生SQL的前提,数据库已经生成,并且有对应的表(以下仅为模拟演示,并非真实场景):操作数据库时,执行如下SQL:很多朋友应该也对这个有疑问当他们看到这个有SQL注入的风险,因为这里的SQL语句看起来就是一个串接的字符串,只是插值运算符的形式,看起来没什么特别的。1.3打印日志查看实际执行的SQL。从表面上看,它确实有风险。既然你说没有,那就出示证据证明,你可以直接把EF执行过程的日志打印出来,看看实际执行的SQL语句是什么样子的;EFCore5.0之后好像提供了一个方便的配置,可以方便的打印相应的SQL记录,所以我们先开启日志打印功能:开启日志后,执行程序看看真正的SQL是什么样的,console可以看到如下日志:可以看到SQL语句已经参数化,没有注入风险。所以为什么?因为ExecuteSqlInterpolatedAsync中SQL语句参数的类型是FormattableString,EFCore内部会根据FormattableString结果生成参数化SQL语句。2.FormattableString有点意思。为了查看FormattableString的功能,搭建一个简单的控制台程序,看看情况,如下:可以看到FormattableString包含了拼接的字符串和对应的参数。得到这些结果后,就可以构造成想要的结果了。2.1在使用var的时候,还是需要稍微注意一下之前的项目。因为使用了var,网上出现了一个bug。代码一一看完,好像没什么问题,开发测试环境也正常,但是线上有问题。最后通过模拟在线数据调试完成。大致使用如下:开发测试环境之所以没问题,是因为没有模拟整个线上环境,所以漏掉了这个bug;对于开发来说,var确实用起来很方便,但是对于类似上述的场景,使用具体的类型会避免一些不必要的bug;代码比较简单,就不提交了~~~总结开发过程中,细节上的一个小改动,可能会有不同的效果;可能会带来非常难排错的bug,开发过程中一定要注意!!!
