FromSqlRaw 可执行 Oracle 原生 SQL,但必须绑定已映射实体、列名严格匹配(大小写敏感)、仅支持位置参数;非完整实体查询应改用 SqlQuery;DML 用 ExecuteSqlRaw/Interpolated;复杂场景(如 RETURNING、REF CURSOR)需回退 ADO.NET。
用 FromSqlRaw 执行 Oracle 原生 SQL 查询(EF Core 5+)
ef core 对 oracle 的原生 sql 支持依赖于数据库提供程序,比如 oracle.entityframeworkcore(oracle 官方提供)或 devart.data.oracle.efcore(devart 第三方)。只要 provider 正确安装并注册,fromsqlraw 就能用,但要注意:oracle 不支持 sql server 那种表值函数式写法,也不能直接对任意 select 语句调用 fromsqlraw——它必须绑定到一个已映射的实体类型。
- 必须配合
DbSet使用,例如context.Users.FromSqlRaw("SELECT * FROM USERS WHERE ROWNUM - SQL 中列名必须与实体属性名(或通过
[Column]映射的列名)严格匹配,大小写敏感(Oracle 默认大写,EF Core 默认按 PascalCase 匹配,容易错) - 不支持参数化查询中的命名参数(如
:name),要用@p0这样的位置占位符(EF Core 统一机制),provider 会自动转换为 Oracle 绑定格式 - 若查询结果不对应完整实体(比如只查几列、含计算字段),应改用
ExecuteSqlRaw或SqlQuery(见下节)
查询非实体结构数据:用 SqlQuery(EF Core 5+)
EF Core 5 引入了 SqlQuery,专为“无映射类”设计,比老版 Database.SqlQuery(已移除)更安全。它不要求 T 是 DbSet 类型,只要字段可映射即可。
-
T必须是普通类(无构造函数限制),且属性名需与 SQL 返回列名一致(同样注意大小写) - 在
OnModelCreating中需显式注册:modelBuilder.Entity(().HasNoKey().ToView(null); ToView(null)表示非视图/表映射) - 调用方式:
context.SqlQuery("SELECT ID, UPPER(NAME) AS NAME FROM USERS").ToList() - 列别名必须用
AS显式声明,否则 Oracle 返回的列名可能是大写原始名(如UPPER(NAME)→UPPER(NAME)),导致映射失败
ExecuteSqlRaw 和 ExecuteSqlInterpolated 用于 DML 操作
执行 INSERT / UPDATE / DELETE / PL/SQL 块时,用这两个方法最直接:
-
ExecuteSqlRaw接收纯字符串 SQL,适合静态语句;ExecuteSqlInterpolated支持内插语法(如$"UPDATE USERS SET NAME = {name} WHERE ID = {id}"),EF Core 自动参数化,避免 SQL 注入 - Oracle 的 PL/SQL 块需用
BEGIN ... END;包裹,且末尾分号不能省略(ExecuteSqlRaw("BEGIN INSERT INTO USERS (ID, NAME) VALUES (1, 'A'); END;")) - 返回值是影响行数(
int),不是结果集;若需返回值(如RETURNING子句),得用 ADO.NET 原生连接(见下节)
需要 RETURNING、REF CURSOR 或复杂 PL/SQL?绕过 EF Core,用原生 OracleConnection
EF Core 的 SQL 执行能力在 Oracle 场景下有明显边界:不支持 RETURNING 子句自动映射、无法消费 REF CURSOR、也不能直接调用带 OUT 参数的存储过程。
- 此时应从
context.Database.GetDbConnection()获取底层OracleConnection,再用OracleCommand手动执行 - 注意连接状态:若
context未开启连接,需先Open();事务需手动关联(command.Transaction = context.Database.CurrentTransaction?.GetDbTransaction()) -
REF CURSOR输出需声明为OracleDbType.RefCursor,再用OracleDataAdapter填充DataTable,EF Core 不参与这层解析
Oracle 的原生 SQL 集成不是“开箱即用”,关键卡点往往在大小写映射、PL/SQL 语法兼容性和结果集结构灵活性上——别硬套 FromSqlRaw,该切 ADO.NET 的时候就切。











