EntityFramework Core 3.1 ORA-01460: unimplemented or unreasonable conversion requested
最近 oracle 更新了EFCore (Oracle.EntityFrameworkCore) 终于支持EFCore (EntityFramework Core) 3.1
升级前:
1 <ItemGroup> 2 <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.6" /> 3 <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" /> 4 <PackageReference Include="Oracle.EntityFrameworkCore" Version="2.19.90" /> 5 </ItemGroup>
升级后:
1 <ItemGroup> 2 <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.8" /> 3 <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" /> 4 <PackageReference Include="Oracle.EntityFrameworkCore" Version="3.19.80" /> 5 </ItemGroup>
但升级以后大量出现以下Exception:
Exception:
Microsoft.EntityFrameworkCore.DbUpdateException: 'An error occurred while updating the entries. See the inner exception for details.' Inner Exception:
OracleException: ORA-01460: unimplemented or unreasonable conversion requested
查看文档,发现是由于c# 类型(byte[])存入 Oracle DB 中的 Blob 类型,在数据超出32K长度后会出现ORA-01460错误。Google、百度均无解决方案。
后因代码优化整理,发现Exception竟然突然消失,后经排查发现是一个ORACEL的小细节引起。
// 优化前 builder.Property(x => x.Photo).HasColumnName("PHOTO").HasColumnType("blob"); // 优化后 public class DbTypeNames { public const string Blob = "BLOB"; } builder.Property(x => x.Photo).HasColumnName("PHOTO").HasColumnType(DbTypeNames.Blob);
因使用 EntityFrameworkCore的 Fluent API 接口,在绑定 Column 时大量使用 HasColumnType,故将 DbType 集中使用常量处理,由于Oracle 编程规范都偏向大写,故所有的column type都改为大写。之后Exception消失。
总结:
在使用 Oracle 类库时,Column Name,Column Type 请完全使用大写。
小分享:
请尽量使用 HasColumnType 声明 POCO (Plain Ordinary C# Object) 属性的数据库类型。最开始的时候我一直是使用省略模式,在省略的情况下根据 Oracle 的官方文档,默认为 string -> varchar2,但由于这个省略曾经引起转换失败,索引没有被触发使用,引起严重的性能问题。