EF Core获取Oracle序列值遇ORA-22806错误求助
解决Oracle序列获取时的ORA-22806错误
问题原因
你当前的代码中,EF会把带字符串插值的SQL($"Select {sequenceList}.NextVal From Dual")自动处理成参数化查询,导致Oracle收到的SQL类似SELECT @p0.NEXTVAL FROM DUAL。这里的@p0是枚举值对应的参数,并非数据库里的序列标识符,Oracle无法将其解析为合法的序列对象,因此抛出ORA-22806: not an object or REF错误。
解决方案
因为序列名称来自枚举(取值固定可控,无SQL注入风险),可以直接把枚举值转为字符串后拼接SQL,不用依赖参数化查询。以下是修正后的代码:
EF6版本
public async Task<long> GetSequenceValue(SequenceList sequenceList) { // 将枚举转换为数据库中对应的序列名称字符串 var sequenceName = sequenceList.ToString(); // 直接拼接SQL,确保序列名称被正确解析为标识符 var query = this.Database.SqlQuery<long>($"SELECT {sequenceName}.NEXTVAL FROM DUAL"); // 用异步方法获取结果,替代同步ToList() var result = await query.FirstOrDefaultAsync(); return result; }
EF Core版本
如果用EF Core,需要改用FromSqlRaw(SqlQuery已被标记为过时):
public async Task<long> GetSequenceValue(SequenceList sequenceList) { var sequenceName = sequenceList.ToString(); var result = await this.Set<long>() .FromSqlRaw($"SELECT {sequenceName}.NEXTVAL FROM DUAL") .FirstOrDefaultAsync(); return result; }
注意事项
- 要确保枚举的名称和数据库中序列的名称完全一致(Oracle大小写敏感,需匹配命名规则)。
- 该方法只适用于枚举取值可控的场景,如果序列名称来自用户输入,需要额外做注入校验。
内容的提问来源于stack exchange,提问作者Bala
相关产品推荐
相关产品推荐

