当前位置:首页 > C# > 正文

EF Core执行原始SQL命令详解(手把手教你用C#直接操作数据库)

在使用 Entity Framework Core(简称 EF Core)进行 C# 开发时,大多数情况下我们通过 LINQ 查询来操作数据库。但有时候,为了更高的性能、更灵活的控制,或者执行一些 EF Core 不支持的特定 SQL 操作(如存储过程、复杂视图等),我们需要直接执行原始 SQL 命令。本文将带你从零开始,详细讲解如何在 EF Core 中安全、高效地执行原始 SQL 命令。

EF Core执行原始SQL命令详解(手把手教你用C#直接操作数据库) Core 原始SQL 数据库操作 C#教程 第1张

一、为什么需要执行原始 SQL?

虽然 EF Core 提供了强大的 ORM 功能,但在以下场景中,使用原始 SQL 更为合适:

  • 调用数据库存储过程
  • 执行复杂的聚合查询或窗口函数
  • 批量更新或删除(避免先加载再修改)
  • 访问 EF Core 尚未支持的数据库特性

二、准备工作:创建 DbContext

首先,确保你已经有一个继承自 DbContext 的类。例如:

public class AppDbContext : DbContext{    public DbSet<Product> Products { get; set; }    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)    {        optionsBuilder.UseSqlServer("Server=.;Database=MyAppDb;Trusted_Connection=true;");    }}  

三、执行原始 SQL 查询数据

EF Core 提供了 FromSqlRawFromSqlInterpolated 方法用于执行原始 SQL 并返回实体集合。

1. 使用 FromSqlRaw(注意 SQL 注入风险)

using var context = new AppDbContext();var products = context.Products    .FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 100)    .ToList();  

⚠️ 注意:FromSqlRaw 不会自动参数化字符串拼接,如果直接拼接用户输入,可能导致 SQL 注入

2. 使用 FromSqlInterpolated(推荐,自动参数化)

decimal minPrice = 100;var products = context.Products    .FromSqlInterpolated($"SELECT * FROM Products WHERE Price > {minPrice}")    .ToList();  

FromSqlInterpolated 会自动将插值表达式转换为参数化查询,有效防止 SQL 注入,是更安全的选择。

四、执行非查询命令(INSERT/UPDATE/DELETE)

对于不返回数据的操作(如更新库存、删除记录等),可以使用 ExecuteSqlRawExecuteSqlInterpolated

// 安全方式:使用参数化int rowsAffected = context.Database.ExecuteSqlInterpolated($@"    UPDATE Products     SET Stock = Stock - 1     WHERE Id = {productId} AND Stock > 0");Console.WriteLine($"{rowsAffected} 行被更新。");  

这些方法返回受影响的行数,可用于判断操作是否成功。

五、调用存储过程

假设数据库中有一个名为 GetProductsByCategory 的存储过程:

string category = "Electronics";var products = context.Products    .FromSqlInterpolated($"EXEC GetProductsByCategory {category}")    .ToList();  

同样建议使用 FromSqlInterpolated 来确保参数安全。

六、注意事项与最佳实践

  • 优先使用参数化查询:始终使用 FromSqlInterpolated 或带参数的 FromSqlRaw,避免字符串拼接用户输入。
  • 结果必须匹配实体结构:原始 SQL 返回的列名必须与实体属性名一致(或通过映射配置)。
  • 不要用于复杂对象图:原始 SQL 通常只适用于单表查询,关联数据需额外处理。
  • 事务支持:可在 Database.BeginTransaction() 中包裹原始 SQL 操作,确保数据一致性。

七、总结

EF Core 的原始 SQL 功能为你在需要时提供了“逃生舱口”,让你既能享受 ORM 的便利,又不失对数据库的完全控制。只要注意安全性和兼容性,就能在项目中灵活运用。无论你是初学者还是有经验的开发者,掌握 EF Core 中的 原始SQL 执行技巧,都能显著提升你的 C#教程 实战能力,优化 数据库操作 效率。

希望这篇教程能帮你轻松上手!如有疑问,欢迎在评论区交流。