首页
编程语言
C#执行原生SQL教程EFCore FromSqlRaw与参数化查询详解
C#执行原生SQL教程EFCore FromSqlRaw与参数化查询详解
# C# 如何执行原生 SQL:EF Core FromSqlRaw 与参数化查询的核心要点
在 EF Core 中使用原生 SQL 查询时,`FromSqlRaw` 是一个强大的工具,但它也像一把双刃剑——用得好能解决复杂查询需求,用不好则可能引入安全漏洞和性能问题。以下是几个必须掌握的核心要点。
## FromSqlRaw 本身不防注入,必须配合参数化写法才安全
直接拼接字符串等于裸奔。EF Core 的 `FromSqlRaw` 方法不会自动识别变量,它只是将传入的字符串原样传递给数据库——除非你显式提供参数。
**错误写法**:`"SELECT * FROM Users WHERE Name = '" + name + "'"`,这会直接触发 SQL 注入攻击。
**正确做法**是使用位置占位符 `{0}` 或 `SqlParameter`:
```csharp
// 使用位置占位符
context.Users.FromSqlRaw("SELECT * FROM Users WHERE Age > {0} AND Status = {1}", 18, "Active")
// 使用 SqlParameter(更灵活,可控制类型)
context.Users.FromSqlRaw("SELECT * FROM Users WHERE Name LIKE @name",
new SqlParameter("@name", "%john%"))
```
前者依靠 EF Core 自动转换为命名参数(如 `@p0`),后者则可以精确控制 `SqlDbType` 和空值处理,通常更稳妥。
## FromSqlRaw 只能用于 DbSet,不能链式调用 Where 等 LINQ 方法
这是一个常见的性能陷阱。你不能在 `FromSqlRaw` 后再写 `.Where(x => x.IsActive)`,因为 EF Core 不会把这些 LINQ 方法翻译成 SQL,而是先执行原始 SQL,然后在内存中进行过滤——数据量大时性能会直接崩盘。
**常见误用**:
```csharp
context.Users
.FromSqlRaw("SELECT * FROM Users")
.Where(u => u.CreatedAt > DateTime.Today) // ❌ 内存过滤!
.ToList();
```
**正确方式**是把条件直接写进 SQL 里:
```csharp
context.Users
.FromSqlRaw("SELECT * FROM Users WHERE CreatedAt > {0}", DateTime.Today)
.ToList();
```
或者改用 `FromSqlInterpolated`(EF Core 5+ 支持),它支持字符串插值且自动参数化,写起来更自然:
```csharp
var cutoff = DateTime.Today;
context.Users
.FromSqlInterpolated($"SELECT * FROM Users WHERE CreatedAt > {cutoff}")
.ToList();
```
## 列名、顺序、类型必须和实体完全一致
`FromSqlRaw` 不做任何字段映射,也不容错。SQL 返回的列必须和实体属性严格匹配:
- **列名必须一致**(大小写敏感,尤其在 PostgreSQL 中)
- **顺序必须一致**(按实体属性定义顺序)
- **类型必须兼容**(比如数据库返回 `datetime2`,实体用 `DateTime?` 却对应了 `NOT NULL` 列)
**常见问题**:
- 少一列 → 未映射属性为默认值
- 多一列 → 直接抛 `InvalidOperationException`
- 类型不兼容 → 运行时失败
**最佳实践**:
1. 别用 `SELECT *`:表结构变更后极易出错
2. 别乱加别名:`SELECT u.Name AS UserName` → 实体必须有 `UserName` 属性
3. 计算列或 `NULL` 值要小心:例如 `SELECT Id, Name, COUNT(*) AS Count`,若实体没 `Count` 属性就失败
需要部分字段?建议新建一个轻量 DTO 类,使用 `AsNoTracking()` + 手动投影,或者换用 `SqlQueryRaw()`(EF Core 5+)。
## 查询完记得加 AsNoTracking()
`FromSqlRaw` 默认开启变更跟踪,哪怕你只是读取报表数据。这会导致 EF Core 缓存所有实体、监听属性变化、额外分配内存——在纯读场景下毫无必要。
加上 `AsNoTracking()` 能显著降低 GC 压力和查询耗时:
```csharp
context.Users
.FromSqlRaw("SELECT Id, Name, Email FROM Users WHERE IsActive = {0}", true)
.AsNoTracking()
.ToList();
```
**注意**:加了 `AsNoTracking()` 之后,实体不可直接修改提交。如需更新,得重新查询或手动 `Attach`。
## 最容易被忽略的细节
在实际项目中,最常被忽略的是列名大小写和空值处理:
1. **跨数据库迁移时**:PostgreSQL 默认小写,SQL Server 默认不敏感但配置可变
2. **NULL 字段映射**:映射到非可空类型会静默失败或报异常,不是所有环境都开启详细日志
这些问题往往在测试环境不出现,一到生产环境就暴露,需要格外注意。
来源:https://www.php.cn/faq/2415863.html
免责声明:
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关攻略
C#执行原生SQL教程EFCore FromSqlRaw与参数化查询详解
EFCore的FromSqlRaw方法可执行原生SQL查询,但需注意安全与性能。必须使用参数化查询防止SQL注入,不可在方法后链式调用LINQ条件以免内存过滤。查询结果列必须与实体属性严格匹配,建议避免SELECT*并显式指定列。纯读取场景应使用AsNoTracking以提升性能。跨数据库时需注意列名大小写与空值映射等细节。
C#大文件分片上传实现方法与断点续传合并文件块教程
大文件分片上传时,客户端将文件分块并附带标识、序号、总块数及哈希值上传,服务端校验存储。断点续传时,客户端根据服务端返回的已接收列表仅上传缺失部分。合并文件需流式写入避免内存溢出,并再次校验块哈希。双方计算总块数的逻辑须严格一致。
C#程序调试的几种常用方法与实战技巧
调试C 程序时断点不生效,常见原因包括项目未设为启动项、生成配置非Debug模式、源码与PDB文件不匹配或断点位置不当。应检查启动项目、Debug配置,并清理生成文件夹。调试多线程或异步任务时,变量可能因上下文问题显示异常,可使用线程窗口、任务窗口和监视窗口辅助定位。
C#资源泄漏的三种隐蔽场景排查与解决方法详解
最近在做项目代码审查时,发现了一个有意思的现象:大家都知道要用 using 或 Dispose() 来释放资源,但真正遇到资源泄漏时,还是一脸懵。有人问我:“刚哥,我都调用 Dispose() 了,为什么内存还在涨?” 这个问题确实问到了点子上。因为 Dispose 不释放 的坑,远比想象的要深。今
编程泛型与元编程核心概念详解
从概念上讲: 咱们不妨先厘清几个基础概念。编程这事儿,说白了,就是让你的程序去处理一段数据。 那元编程呢?它更进了一步,指的是你的程序被设计用来处理其他程序——或者说,处理代码本身。 至于泛型编程,它的核心魅力在于抽象。你的程序实现了一种功能,而这种功能的神奇之处在于,它能够游刃有余地处理多种不同类
热门推荐
OKX购买USDT新手教程:从注册到交易完整步骤详解
购买USDT是进入加密货币世界的重要一步。本文以OKX平台为例,详细介绍了从注册、身份认证到完成购买的完整流程,涵盖了快捷买币、C2C交易等不同方式的操作要点与注意事项,旨在帮助新手安全、顺利地迈出第一步。
Windows 11 任务管理器新增AI硬件监控与NPU性能监测
Windows任务管理器,终于跟上了AI时代 几十年来,Windows任务管理器堪称操作系统的“老伙计”,忠实记录着每一个进程的脉搏。但眼下,这位老将遇到了新挑战:它必须得追上一波十年前根本无法想象的技术浪潮。最典型的例子是什么?就是你新买的电脑里,很可能已经多了个叫“神经网络处理单元”(NPU)的
Safari预览版十周年版本累计更新240次回顾苹果Web技术探索历程
苹果前沿 Web 技术试验田:Safari 预览版浏览器迎 10 周年,版本累计更迭 240 次 十年,对于一个快速迭代的科技产品来说,足以称得上一个里程碑。就在最近,苹果专门为开发者打造的浏览器测试工具——Safari 技术预览版,悄然迎来了它的十周岁生日。 故事要回溯到2016年3月30日。当时
C4D教程TFD插件制作逼真烟雾效果详细步骤
C4D怎么使用TFD插件制作烟雾效果呢? 说起在Cinema 4D里模拟烟雾效果,TFD(TurbulenceFD)插件绝对是很多高手的首选工具。不过,对于刚接触它的朋友来说,那一堆参数和设置可能有点让人无从下手。别担心,下面这份详细的流程图解式教程,将一步步带你从零开始,制作出细节丰富、动态真实的
Cinema 4D制作线型三维立体圆环纹理详细步骤指南
C4D必备技能:手把手教你打造三维线状圆环图纹 想要在Cinema 4D中创建出那种充满科技感和结构美的三维线状圆环图纹吗?这个效果在动态图形和视觉包装中应用广泛,制作过程其实并不复杂。掌握了核心的操作逻辑,几步就能实现,下面就为你拆解整个操作流程。 C4D怎么创建三维立体的线状圆环图纹效果 首先,