EF Core 中避免 SQL 注入的三种写法

SQL 注入攻击可能会对我们的应用程序产生严重影响,导致敏感数据泄露、未经授权的访问和应用程序受损。EF Core 提供了三种内置机制来防止 SQL 注入攻击。

1、利用 LINQ 查询语法和参数化查询,这是比较推荐的做法。

await using var context = new PostgresContext();  
var author = "江";  
var blog = await context.Blogs.Where(s=>s.Author == author + "山").FirstOrDefaultAsync();

生成的查询脚本如下:

SELECT b.author, b.blogid, b.url
FROM blog AS b
WHERE b.author = @__p_0
LIMIT 1

2、使用 FromSql

对于一些复杂的查询,需要直接使用 SQL 查询脚本的,如果是 EF Core 7.0 以上版本可以使用 FromSql。

await using var context = new PostgresContext();  
var author = "江山";
var blog = await context.Blogs.FromSql($"SELECT * FROM blog WHERE author = '{author}'").FirstOrDefaultAsync();

生成的查询脚本如下:

SELECT e.author, e.blogid, e.url
FROM (
    SELECT * FROM blog WHERE author = '@p0'
) AS e
LIMIT 1

它会自动识别字符串中的 {author} 这样的字符,用参数替换掉。

3、使用 FromSqlRaw

FromSqlRaw 也可以执行 SQL,但是需要特别注意。

先看下面的代码:

await using var context = new PostgresContext();  
var author = "江山";    
var blog = await context.Blogs.FromSqlRaw("SELECT * FROM blog WHERE author = '{0}'",author).FirstOrDefaultAsync();

生成的查询脚本如下:

SELECT e.author, e.blogid, e.url
FROM (
    SELECT * FROM blog WHERE author = '@p0'
) AS e
LIMIT 1

上面的结果是安全的。现在,把脚本改成"+"号拼接:

var blog = await context.Blogs.FromSqlRaw("SELECT * FROM blog WHERE author = '"+author+"'").FirstOrDefaultAsync();

生成的脚本如下:

SELECT e.author, e.blogid, e.url
FROM (
    SELECT * FROM blog WHERE author = '江山'
) AS e
LIMIT 1

这样就不安全了。

这就是 EF Core 中避免 SQL 注入的三种方式,希望对你有帮助。

### C# EF6.0 Update 实现方式 在C#中使用Entity Framework 6.0(EF6.0)进行数据更新操作时,通常需要先从数据库中查询出目标实体对象,然后修改其属性值,并调用`SaveChanges()`方法将更改保存到数据库中。以下是具体的实现方式和示例代码。 #### 示例代码 以下是一个完整的示例,展示如何使用EF6.0更新数据库中的数据: ```csharp using System; using System.Linq; using Microsoft.EntityFrameworkCore; namespace EFUpdateExample { public class BloggingContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } } public class Program { public static void Main() { using (var context = new BloggingContext()) { // 查询要更新的记录 var blogToUpdate = context.Blogs.FirstOrDefault(b => b.BlogId == 1); if (blogToUpdate != null) { // 修改属性值 blogToUpdate.Url = "https://newurl.com"; // 提交更改 context.SaveChanges(); Console.WriteLine("博客URL已成功更新!"); } else { Console.WriteLine("未找到指定的博客记录。"); } } } } } ``` #### 注意事项 1. 在查询数据时,**不要使用`AsNoTracking()`方法**,否则实体对象将不会被上下文跟踪,导致无法更新数据[^3]。 2. 更新操作的核心在于对查询结果的属性进行修改后调用`SaveChanges()`方法,这会将更改同步到数据库中[^3]。 3. 如果需要批量更新,可以考虑使用原始SQL语句或第三方库(如EntityFramework.Extended),以提高性能[^2]。 #### 使用原始SQL语句进行更新 如果需要直接执行SQL语句来完成更新操作,可以使用`DbContext.Database.ExecuteSqlRaw`或`ExecuteSqlCommand`方法。例如: ```csharp using (var context = new BloggingContext()) { context.Database.ExecuteSqlRaw("UPDATE Blogs SET Url = {0} WHERE BlogId = {1}", "https://newurl.com", 1); Console.WriteLine("博客URL已通过SQL语句成功更新!"); } ``` 这种方法适用于需要高效执行批量更新或复杂更新逻辑的场景[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LeiCodeX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值