識別子名の長さと一意性

バージョン12.2より前のOracle Databaseでは、表名、列名、主キー名などの識別子名が30文字に制限されています。Oracle Database 12.2以上では、デフォルトの制限は128文字です。

Entity Framework Core移行では、Oracle Databaseバージョンでサポートされる長さを超える識別子名が作成されないように、これらの識別子の長さを制限する必要があります。データベースでサポート可能な長さを超える識別子を作成しようとすると、通常、「ORA-00972: 識別子が長すぎます。」というエラーが発生します。

RelationalModelAnnotations MaxIdentifierLengthプロパティ(EF Core 2.x)またはModelBuilder HasAnnotationメソッド(EF Core 3.x)を使用して、ターゲット・データベース・バージョンで処理できる最大識別子長を設定します。たとえば、Oracle Database 11.2を使用している場合は、30 (以下)に設定する必要があります。設定すると、Entity Framework Coreでは、長すぎる識別子名を指定の長さまで自動的に切り捨てます。これによって、ユーザーおよびEntity Framework Coreが、接続しているOracle Databaseバージョンの最大文字数制限を超える識別子を作成するのを防ぎます。

// C# Sample Code: Setting maximum identifier length to 30 characters; By default, it's set to 128.
modelBuilder.Model.Relational().MaxIdentifierLength = 30;

Entity Framework Core 2.xには、最大識別子長より長い識別子名を単に切り捨てるだけで、一意にすることはないという既知の問題があります。また、MaxIdentifierLengthは、エンティティ・クラス名に基づいて作成される表名の長さの制御に対して影響を与えません。これらの問題はEntity Framework Core 3.xで解決されています。

一方、この問題の次善策として、クラス名やプロパティ名などの名前を変更するか、またはToTable()/HasColumnName() Fluent APIか同等のデータ注釈を使用して、Oracleデータベースで作成される表/列に対してより短縮された名前または一意の名前(あるいはその両方)を指定します。

識別子にマルチバイト文字が使用されている場合は、Oracleデータベースですべての識別子を作成できるように、MaxIdentifierLengthで文字拡張比率の設定が必要になる場合があります。たとえば、Oracleデータベースの文字セットがUTF8の場合は、1文字に最大4バイトが必要です。したがって、長い識別子をサポートしないOracleデータベースですべての識別子を作成できるようにするには、MaxIdentifierLengthを7文字(つまり、30文字を4で除算)に設定する必要があります。

使用しているデータベース・バージョンがサポートしているよりも長い識別子名をEF Coreモデルで使用していない場合でも、MaxIdentifierLengthを設定する必要があります。ODP.NETおよびEntity Framework Coreでは、モデルからスキーマ・オブジェクト名が自動生成されます。場合によっては、データベース・バージョンで許可されている最大文字数を超える文字を名前に追加できます。MaxIdentifierLengthを設定することによって、EF CoreでORA-00972が誤って発生するのを防ぎます。