前言

接下来一段时间我们来讲讲EntityFramework Core基础,精简的内容,深入浅出,希望为想学习EntityFramework Core的童鞋提供一点帮助。

EntityFramework Core执行原始查询

在EntityFramework Core中执行原始查询我们借助FromSql来实现,如下:

using (var context = new EFCoreDbContext())

{

var orders = context.Orders

.FromSql("SELECT * FROM dbo.Orders")

.ToList();

}

这是最简单且不带任何条件的查询方式,接下来我们看看有条件的查询我们应该如何查询,如下:

using (var context = new EFCoreDbContext())

{

var parameters = new SqlParameter[]

{

new SqlParameter(){ ParameterName = "@p0", Value = 1, SqlDbType = System.Data.SqlDbType.Int }

};

var orders = context.Orders

.FromSql("SELECT * FROM dbo.Orders WHERE Id = @p0", parameters)

.ToList();

}

除了以上利用参数化查询方式外,若我们还借助string.format或者C# 6.0出现的新特性字符串插值即美元符号$来查询最终生成的SQL是否仍然是以参数化查询呢,我们来看看。

using (var context = new EFCoreDbContext())

{

var orders = context.Orders

.FromSql($"SELECT * FROM dbo.Orders WHERE Id = {1}")

.ToList();

}

由上我们看出即使利用字符串插值最终仍然翻译成参数化SQL。接下来我们再来看看字符串拼接查询方式。

using (var context = new EFCoreDbContext())

{

var searchString = "Jeffcky";

var blogs = context.Blogs

.FromSql("SELECT Id, Name, CreatedTime, Url, ModifiedTime FROM dbo.Blogs " +

"WHERE Name = '" + searchString + "'")

.ToList();

}

此时我们通过控制台打印能够看出最终生成的SQL语句是以字符串形式展示,在EntityFramework Core 2.0+上执行原始查询的APi即FromSql有重载方法,如下:

public static IQueryable<TEntity> FromSql<TEntity>([NotNullAttribute] this IQueryable<TEntity> source, [NotNullAttribute][NotParameterized] FormattableString sql) where TEntity : class;

我们利用上述FromSql重载方法传递字符串参数,同时在查询字符串中添加对数据库表操作,验证EF Core是否能防止SQL注入。

using (var context = new EFCoreDbContext())

{

var searchString = "Jeffcky; DROP TABLE dbo.Blogs;";

var blogs = context.Blogs

.FromSql("SELECT Id, Name, Url, CreatedTime, ModifiedTime FROM dbo.Blogs "

+ " WHERE Name = {0}", searchString)

.ToList();

}

经过验证您会发现上述我们注入上述Blogs表的SQL语句,最终表将不会删除。我们看到当未利用重载方法进行字符串拼接,此时参数将以字符串形式展示,这种情况极易引起SQL注入问题。C# 6.0引入了字符串插值(String Interpolation),此特性能够允许C#表达式直接嵌入到字符串文本中,为运行时构建字符串提供了一个很好的方法。在EF Core 2.0特性中,对FromSql和ExecuteSqlCommand方法都添加了对插入字符串的特殊支持。此新特性的支持允许以安全的方式使用C#字符串插值。即防止在运行时动态构建SQL时可能发生SQL注入问题。

是不是到了这里就这样结束了呢?显然不是这样,接下来咱们再来看看另外一种情况,如下:

using (var context = new EFCoreDbContext())

{

var author = "Jeffcky Wang";

var query = $"SELECT * FROM Blogs WHERE Name = {author}";

var blogs = context.Blogs.FromSql(query).ToList();

}

这样的语法错误显而易见,我们需要用单引号将变量包含起来才能避免语法错误,如下:

using (var context = new EFCoreDbContext())

{

var author = "Jeffcky Wang";

var query = $"SELECT * FROM Blogs WHERE Name = '{author}'";

var blogs = context.Blogs.FromSql(query).ToList();

}

上述情况下,EF Core依然将执行明文字符串而不是作为变量查询并未以参数化执行。如果变量包含恶意字符串,那么EF Core将根本无法防范并保护SQL。因此,如果我们需要通过EF Core执行原始T-SQL,则应使用参数化SQL或利用FormatttableString,FromSql有两个重载,其一为通过FormatttableString可格式化字符串参数,其二为原始字符串且可传递查询参数。所以上述错误,我们可利用FormatttableString来执行,同时在利用FromSql方法查询过后我们仍可以继续进行查询,比如如下关联查询Posts表数据。

using (var context = new EFCoreDbContext())

{

var searchString = "Jeffcky Wang";

FormattableString sql = $@"SELECT Id, Name, Url, CreatedTime, ModifiedTime FROM dbo.Blogs WHERE Name = {searchString}";

var blogs = context.Blogs

.FromSql(sql)

.Include(d => d.Posts)

.ToList();

}

通过【$@】并利用FormattableString重载或者传递参数化变量来防止SQL注入问题,希望您发现EF Core 2.0中这个新特性,同时不要忘记它也用来承担更大的责任,由于SQL注入攻击,不会让我们所写代码存在漏洞。

总结

本节我们详细讲解了EF Core 2.0中执行原始查询如何防止SQL注入问题,精简的内容,简单的讲解,希望能帮助到您。我们明天再会。

原文:https://www.cnblogs.com/CreateMyself/p/8481331.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

EntityFramework Core 2.0执行原始查询如何防止SQL注入?相关推荐

  1. EntityFramework Core 2.0自定义标量函数两种方式

    前言 上一节我们讲完原始查询如何防止SQL注入问题同时并提供了几种方式.本节我们继续来讲讲EF Core 2.0中的新特性自定义标量函数. 自定义标量函数两种方式 在EF Core 2.0中我们可以将 ...

  2. EntityFramework Core 3.0 Preview

    前段时间.Net Core 3.0 发布了,Entity Framework Core 3.0 也发布了Preview版.假期用了一上午大致研究了一遍,同时又体验了一把Visual Studio 20 ...

  3. 视图函数中进行sql查询,防止sql注入

    视图函数中进行sql查询 import pymysql # 创建连接 use_unicode=true指定字符的编码.解码格式,进行自动编码解码,mysql数据库的编码格式为gbk,而项目数据库为ut ...

  4. 参数化查询为什么能够防止SQL注入

    很多人都知道SQL注入,也知道SQL参数化查询可以防止SQL注入,可为什么能防止注入却并不是很多人都知道的. 本文主要讲述的是这个问题,也许你在部分文章中看到过这块内容,当然了看看也无妨. 首先:我们 ...

  5. EntityFramework Core 5.0 VS SQLBulkCopy

    [导读]EF Core 5.0伴随着.NET 5.0发布已有一段时日,本节我们来预估当大批量新增数据时,大概是多少区间我们应该考虑SQLBulkCopy而不是EF Core SQLBulkCopy早出 ...

  6. 使用jdbc执行SQL实现登录查询2-避免SQL注入版

    配置文件及工具类参考1 package com.jdsc;import javax.rmi.CORBA.Util; import java.sql.*; import java.util.Scanne ...

  7. PrepareStatement对象(新增、删除、更新、查询、防止SQL注入)

    MySQL三十三:PrepareStatement对象 PrepareStatement 可以防止SQL注入,并且效率高! 1.新增 package lesson03;import lesson02. ...

  8. pdo连接mysql 注入_使用PDO查询mysql避免SQL注入

    使用传统的 mysql_connect .mysql_query方法来连接查询数据库时,如果过滤不严紧,就有SQL注入风险.虽然可以用mysql_real_escape_string()函数过滤用户提 ...

  9. mysql参数化查询为什么可以实现_为什么参数化SQL查询可以防止SQL注入?

    SQL 语句文本对于数据库来说,是一种指令,与 Shell 中输入的一条条命令行很类似.我们在 SQL 中混入的各种值就是操作的参数. 考虑一个 WHERE user_id = 10 的筛选,WHER ...

最新文章

  1. ORACLE JET BASIC TABLE
  2. Python3.6.4 安装
  3. MTK6589下传感器框架结构和代码分析以及传感器的参数指标
  4. 37. Leetcode 100. 相同的树 (二叉树-二叉树性质)
  5. JSONObject和JSONArray的关系
  6. java文档注释生产api没有注释_一个神奇的没有springboot注释的api文档生成器---JApiDocs...
  7. C语言实现去掉字符串中指定的字符
  8. 你以为熬个3年工作经验就是Java高级开发了?
  9. 修复Oracle9i中DBA的密码
  10. java 小数 乘法_javascript(js)的小数点乘法除法-Java架构师必看
  11. 螺旋矩阵(递归问题)
  12. 如何理解,互联网架构“高并发”?
  13. php正则 替换div标签内容,PHP 正则匹配标签内容,根据字符串长度进行替换
  14. [C/C++11语法]_[0基础]_[lamba 表达式介绍]
  15. MQ消息队列的优缺点介绍以及对比选型
  16. 什么是项目管理?怎么管?(一)
  17. oracle sys改密码,忘记oracle的sys用户密码怎么修改
  18. 2022年「博客之星」参赛博主:(天寒雨落)在等您评价 ~{附实时总榜单排名}
  19. 9343拆机 xps13_《拆机Pa》十二期 第二代XPS 13是进步还是退步
  20. Surround360 README文档——中文翻译

热门文章

  1. 多线程-单生产单消费模型
  2. 《Unity着色器和屏幕特效开发秘笈(原书第2版)》一2.9 打包和混合纹理
  3. IOZONE测试工具使用方法(转载)
  4. IPV6迎来商业元年 运营商短期盈利模式成难点
  5. [笔记].STM32 BOOT[0:1]启动设置
  6. .NET 6新特性试用 | LINQ功能改进
  7. GitHub Universe 2021|MS Reactor 邀你共聚年度盛会
  8. 为什么应该用record来定义DTO(续)
  9. [C#.NET 拾遗补漏]16:几个常见的TAP异步操作
  10. 很遗憾,总对工作挑挑拣拣的家伙,一般结局都不会太好