当前位置: 首页 > news >正文

EF Core 执行原生SQL语句

文章目录

  • 前言
  • 一、执行查询(返回数据)
    • 1) 使用 FromSqlRaw或 FromSqlInterpolated 方法,适用于 DbSet<T>,返回实体集合。
    • 2)结合 LINQ 查询
    • 3)执行任意原生SQL查询语句(使用ADO.Net)
  • 二、执行非查询操作(增删改)
    • 1)使用 ExecuteSqlRaw() 或 ExecuteSqlInterpolated() 、ExecuteSqlInterpolatedAsync()方法,返回受影响的行数。
  • 三、调用存储过程
    • 1)执行查询存储过程
    • 2)执行非查询存储过程
  • 四、事务处理
    • 1)确保多个 SQL 操作原子性
  • 五、原生 SQL 查询的注意事项
  • 总结


前言

为什么要写原生SQL语句?

  1. 尽管EF Core已经非常强大,但是任然存在着无法被写成标准EF Core调用方法的SQL语句,少数情况下任然需要写原生SQL。
  2. 存在问题:可能无法跨数据库操作。

一、执行查询(返回数据)

1) 使用 FromSqlRaw或 FromSqlInterpolated 方法,适用于 DbSet,返回实体集合。

示例:查询数据(建议使用FromSqlInterpolated,防止SQL注入

var blogs = context.Blogs.FromSqlRaw("SELECT * FROM Blogs WHERE Rating > {0}", 3).ToList();// 或使用插值字符串(参数化,防注入)
var rating = 3;
var blogsSafe = context.Blogs.FromSqlInterpolated($"SELECT * FROM Blogs WHERE Rating > {rating}").ToList();

2)结合 LINQ 查询

var filteredBlogs = context.Blogs.FromSqlInterpolated("SELECT * FROM Blogs").Where(b => b.Url.Contains("dotnet")).OrderBy(b => b.Rating).ToList();

3)执行任意原生SQL查询语句(使用ADO.Net)

DbConnection conn=dbContext.Database.GetDbConnection();
if (conn.State != ConnectionState.Open)
{ conn.Open();
}
using (var cmd = conn.CreateCommand())
{cmd.CommandText = "select Title,Content from T_Articles where Title like '%反反复复%'";using (var reader = await cmd.ExecuteReaderAsync()){while (await reader.ReadAsync()){string title = reader.GetString(0);string content= reader.GetString(1);Console.WriteLine(title+","+content);}}}

二、执行非查询操作(增删改)

1)使用 ExecuteSqlRaw() 或 ExecuteSqlInterpolated() 、ExecuteSqlInterpolatedAsync()方法,返回受影响的行数。

示例:更新数据

var rowsAffected = context.Database.ExecuteSqlRaw("UPDATE Blogs SET Rating = 5 WHERE Name LIKE '%EF Core%'");// 参数化示例
var minRating = 3;
var rowsSafe = await context.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Blogs WHERE Rating < {minRating}");

三、调用存储过程

1)执行查询存储过程

var blogs = context.Blogs.FromSqlRaw("EXEC GetTopRatedBlogs @p0", 5).ToList();

2)执行非查询存储过程

context.Database.ExecuteSqlRaw("EXEC ArchiveOldBlogs @p0", DateTime.Now.AddYears(-1));

四、事务处理

1)确保多个 SQL 操作原子性

using (var transaction = context.Database.BeginTransaction())
{try{context.Database.ExecuteSqlRaw("UPDATE Blogs SET Rating = 5 WHERE BlogId = 1");context.Database.ExecuteSqlRaw("DELETE FROM Blogs WHERE BlogId = 2");transaction.Commit();}catch{transaction.Rollback();}
}

五、原生 SQL 查询的注意事项

  1. 参数化查询:始终使用参数化输入(如 {0} 或插值语法)避免 SQL 注入。
  2. 列匹配:查询返回的列名必须与实体属性名匹配,或通过 AS 别名映射。
  3. 跟踪变更:默认跟踪实体变更,若无需跟踪可加 .AsNoTracking()。
  4. 数据库兼容性:SQL 语法需适配具体数据库(如 SQL Server 和 SQLite 的差异)。
  5. 性能:仅在必要时使用原生 SQL,优先选择 LINQ 以保证类型安全和可维护性。

总结

一般情况下Linq操作就足够了,尽量不要用原生SQL。

  1. EF Core 的原生 SQL 方法适用于特定场景,但需谨慎使用以确保安全性和可维护性。优先考虑 LINQ,复杂场景再选择原生 SQL
  2. 非查询SQL用ExecuteSqlInterpolatedAsync()
  3. 针对实体的SQL查询用FromSqlInterpolated()
  4. 复杂SQL查询用ADO.NET的方式或者Dapper等。

http://www.mrgr.cn/news/96076.html

相关文章:

  • 每天认识一个设计模式-建造者模式:复杂对象的“装配式革命“
  • 05.AI搭建preparationの(transformers01)BertTokenizer实现分词编码
  • EMC知识学习一
  • 2.7 进度控制习题-2
  • 【AI学习】Transformer 模型
  • ffmpeg+QOpenGLWidget显示视频
  • Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·上】
  • Deepseek API+Python 测试用例一键生成与导出 V1.0.4 (接口文档生成接口测试用例保姆级教程)
  • 深度学习框架PyTorch——从入门到精通(10)PyTorch张量简介
  • Windows命令提示符(CMD) 中切换目录主要通过 cd(Change Directory)命令实现
  • WPF InkCanvas 控件详解
  • package.json版本前缀
  • 零拷贝原理面试回答(参考小林Coding)
  • 蓝桥杯题型分布2
  • LLM - R1 强化学习 DRPO 策略优化 DAPO 与 Dr. GRPO 算法 教程
  • 可视化工具TensorBoard
  • AI小白的第八天:梯度下降(含代码实现)
  • AI数据分析:一键生成数据分析报告
  • Unity URP自定义Shader支持RenderLayer
  • 云资源开发学习应用场景指南,场景 1 云上编程实践平台