EFCore通过 LINQ 语法为我们提供了非常便利的方式来操作数据库。
当有些业务逻辑较复杂而不能使用 LINQ 来查询时,可以使用原生 SQL 查询。
或者使用 LINQ 查询导致 SQL 查询效率低下时,也可以使用原生 SQL 查询。
EFCore为我们提供以下几种方式来执行原生SQL语句
- _dbContext.Database.ExecuteSqlRawAsync($"SELECT * FROM ExceptionLog WHERE Logged<='{endDate}'")
-
- //变量endDate为2022-06-27 13:41:25时生成的SQL语句如下:
- SELECT * FROM log.ExceptionLog WHERE Logged<='2022-06-27 13:41:25'
此种方式一定要确保参数 endDate 是经过验证的,否则会产生SQL注入的风险。
可以通过使用形参占位符并提供额外的实参的方式,EFCore会帮我们把参数包装成DbParameter,从而来避免产生SQL注入的风险。
- _dbContext.Database.ExecuteSqlRawAsync("SELECT * FROM ExceptionLog WHERE Logged<={0}",endDate)
-
- //生成的SQL语句如下,{0}占位符会包装成参数@p0
- SELECT * FROM log.ExceptionLog WHERE Logged<=@p0
如果你非得想使用字符串内插的方式,那么EFCore也很贴心,为我们提供了以下方法
- _dbContext.Database.ExecuteSqlInterpolatedAsync($"SELECT * FROM ExceptionLog WHERE Logged<={endDate}")
-
- //生成的SQL语句如下,{endDate}内插字符串变量会被包装成参数@p0
- SELECT * FROM log.ExceptionLog WHERE Logged<=@p0
此种方式EFCore会自动把内插变量包装成DbParameter来实现参数化查询,既满足了我们使用内插字符串的需求,又实现了抵御 SQL 注入攻击,赞![]()