最近 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,但由於這個省略曾經引起轉換失敗,索引沒有被觸發使用,引起嚴重的性能問題。