日本語PDF

Code First

Entity Framework Code Firstのモデリング・パスを使用して、開発者はデザイナまたはXMLベースの構成ファイルを直接操作するのではなくソース・コードを使用するアプリケーション・ドメイン・モデルを定義します。ソース・コード内で定義されるクラスがモデルになります。Code Firstモデル・パスは、Entity Framework Database FirstおよびModel Firstの既存のパスのかわりに使用できます。Code Firstでは、モデルを構成するコードに定義されるクラスをPlain Old CLR Object (POCO)と言います。この名前は、これらのクラスがEntity Framework自体には依存せず、それから独立していることに由来します。

Code Firstモデリング・パスはOracleでサポートされているため、.NET開発者はOracle Databaseの利点を活用できます。

.NETタイプからOracleタイプへのマッピング

Code Firstパスを使用するとき、モデルはアプリケーションのクラスおよびプロパティによって定義されます。プロパティ・データ型をOracle Database表のデータ型にマップする必要があります。次の表に、サポートされている.NETタイプからOracleタイプへのデフォルトのマッピングと、Stringプロパティをデフォルト以外のOracleタイプにマップする方法をリストします。

表4-24 .NETデータ型からOracleデータ型へのマッピング

.NETデータ型 Oracleデータ型 マッピング・メソッド

Boolean

number(1, 0)

EDMマッピングを使用

注意: EDMマッピング構成を使用する必要があります。詳細は、ドキュメントでEDMマッピングに関する項を参照してください。

Byte

number(3, 0)

EDMマッピングを使用

注意: EDMマッピング構成を使用する必要があります。詳細は、ドキュメントでEDMマッピングに関する項を参照してください。

Byte[]

blob

デフォルト

Int16

number(5, 0)

デフォルト

注意: 整数型のデフォルトのマッピングは、EDMマッピング構成で指定される可能性があります。詳細は、ドキュメントでEDMマッピングに関する項を参照してください。

Int32

number(10, 0)

デフォルト

注意: 整数型のデフォルトのマッピングは、EDMマッピング構成で指定される可能性があります。詳細は、ドキュメントでEDMマッピングに関する項を参照してください。

Int64

number(19, 0)

デフォルト

注意: 整数型のデフォルトのマッピングは、EDMマッピング構成で指定される可能性があります。詳細は、ドキュメントでEDMマッピングに関する項を参照してください。

Decimal

number(18, 2)

デフォルト

Single

binary_float

デフォルト

Double

binary_double

デフォルト

Guid

raw(16)

デフォルト

DateTime

date

デフォルト

DateTimeOffset

timestamp with time zone

デフォルト

String

nclob

デフォルト

String

clob

IsUnicode() Fluent APIを使用して、Unicodeをfalseに設定します。

String

nvarchar2

HasMaxLength() Fluent APIまたはMaxLengthデータ注釈を使用して、Max Lengthを<= 2000に設定します。

String

varchar2

HasMaxLength() Fluent APIまたはMaxLengthデータ注釈を使用して、Max Lengthを<= 4000に設定し、IsUnicode() Fluent APIを使用してUnicodeをfalseに設定します。

String

nchar

HasMaxLength() Fluent APIまたはMaxLength注釈を使用して、Max Lengthを<= 1000に設定し、HasColumnType() Fluent APIまたはColumnデータ注釈を使用してColumn TypeをNCHARに設定します。

String

char

HasMaxLength() Fluent APIまたはMaxLength注釈を使用して、Max Lengthを<= 2000 に設定し、HasColumnType() Fluent APIまたはColumnデータ注釈を使用してColumn TypeをCHARに設定します

String

Long

HasColumnType() Fluent APIまたはColumnデータ注釈を使用して、Column TypeをLONGに設定します。

注意: longデータ型は非推奨となったため、使用しないでください。

String

rowid

HasColumnType() Fluent APIまたはColumnデータ注釈を使用して、Column TypeをROWIDに設定します。

String

urowid

HasColumnType() Fluent APIまたはColumnデータ注釈を使用して、Column TypeをUROWIDに設定します。

注意:

文字ベースの列、たとえばCHARNCHARVARCHAR2NVARCHAR2は、文字セマンティクスを使用して作成され、指定したMax Lengthの長さの文字を格納できます。ただし、Oracleデータベースの制限により、これらの列には最大4000バイトまでしか格納できません。したがって、データとデータベースのキャラクタ・セットによっては1文字に複数バイト分の容量を必要とする場合があるため、これらの列ではたとえMax Length4000文字に設定しても4000文字は格納できない場合があります。文字データが4000バイトより長くなる可能性がある場合は、CLOB列またはNCLOB列を使用する方が適切です。

Oracleデータ型の特性に対する影響

前述の表にリストした型のマッピングは、デフォルトで発生するマッピング、つまりEntity Frameworkで規則として知られているマッピングです。String型で説明しているように、プロパティに対して生成されるOracleデータ型と、そのデータ型の特性に対して影響を及ぼすことができます。生成されるOracleデータ型に影響を及ぼすEntity Frameworkの方法には、データ注釈とCode First Fluent APIの2つがあります。データ注釈の場合は1つ以上の属性でクラス・プロパティを明示的にマークすることができ、Code First Fluent APIの場合は属性ではなくコードを使用して同じ目標を達成できます。データ注釈とCode First Fluent APIに関する詳細は、MSDNでEntity Frameworkのドキュメントを参照してください。

次の表で、使用可能な機能を説明します。

表4-25 データ注釈とCode First Fluent APIのマッピング

データ注釈 Fluent API 用途 適用対象

Key

HasKey

プロパティを主キーとして設定します。

すべてのスカラー型

Required

IsRequired

データベース列をNOT NULLに設定します。

すべて

MaxLength

HasMaxLength

プロパティの最大長を指定します。

String

NotMapped

Ignore

プロパティがデータベース列にマップされていないことを示します。

すべて

ConcurrencyCheck

IsConcurrencyToken

オプティミスティックな同時実行性チェックのために列を使用する必要があることを示します。

注意: LOB列が作成されることになるため、無制限の(最大長の指定がない)文字列プロパティでは使用しないでください。同時実行性チェックでLOB列を使用すると、「ORA-00932: データ型が一致しません」エラーになります。

すべて

TimeStamp

IsRowVersion

列をrowversion列として作成するよう指示します。

サポート対象外

Column

HasColumnType

データベース列に使用するプロバイダ固有のタイプを指定します。

注意: 適切な互換性タイプである必要があります。たとえば、Dateプロパティは数値列にマップするには適切ではありません。タイプを指定するColumnデータ注釈とともにTypeNameプロパティを使用します。

すべて

N/A

IsUnicode

列をN-型、つまりnvarchar2またはnclobとして作成するよう指示します。デフォルトはtrueです。

注意: IsUnicodeに相当するデータ注釈はありません。

String

N/A

HasPrecision

小数点プロパティに使用する精度とスケールを指定します。

注意: HasPrecisionに相当するデータ注釈はありません。

Decimal

Code First Migrations

Oracle Data Provider for .NETは、Code First Migrations機能をサポートしています。Code First MigrationsとOracle Databaseの併用は、Package Manager Consoleウィンドウの移行コマンドを通じてサポートされます。これらのコマンドの詳細は、MSDNのCode First Migrationsに関するドキュメントを参照してください。

http://msdn.microsoft.com/en-us/data/jj591621.aspx

Code First Migrationsは、移行履歴表という表を使用して移行操作とモデル変更を追跡します。ODP.NETのデフォルトでは、コンテキスト接続文字列で指定されたユーザー・スキーマにこの表が作成されます。この表は__MigrationHistoryという名前です。

この表は、コンテキスト接続文字列で指定されたユーザー以外のユーザー・スキーマに作成することができます。これは、移行履歴表のカスタマイズというプロセスを通じて実行されます。このプロセスについては、MSDNで次のドキュメントを参照してください。

http://msdn.microsoft.com/en-us/data/dn456841

注意:

  • カスタマイズがサポートされているのは、表のユーザー・スキーマの変更のみです。

  • Code Firstの自動移行が機能するのは、dboスキーマのみに限定されています。この制限があるため、コードベースの移行を使用する、つまりAdd-Migrationコマンドによって明示的な移行を追加することをお薦めします。

サポートしているコード移行ファイルのないCode First Migrations

ODP.NETでCode First Migrationsを使用している場合、データベースを更新する前にサポートされているコード移行ファイルが存在しない場合、移行履歴表がドロップされる可能性があります。開発者は、データベースを更新する前にサポートされているコード移行ファイルが追加されていることを確認してください。

次のステップで、移行履歴表を削除できます。

  1. アプリケーションを実行して、データベース・オブジェクトを作成します

  2. Package Manager ConsoleでEnable-Migrationsを実行します

  3. コードをPOCOに変更します

  4. Package Manager ConsoleでUpdate-Databaseを実行します

次のステップで、コード移行ファイルを作成します。

  1. アプリケーションを実行して、データベース・オブジェクトを作成します

  2. Package Manager ConsoleでEnable-Migrations を実行します

  3. コードをPOCOに変更します

  4. Package Manager ConsoleでAdd-Migration を実行します。このステップは必要なコード移行ファイルを作成します。

  5. Package Manager ConsoleでUpdate-Databaseを実行します

Code Firstデータベースの初期化

ODP.NETでは、Code Firstデータベースを初期化する次のメソッドがサポートされています。

  • CreateDatabaseIfNotExists (何も指定しない場合はデフォルト)

  • DropCreateDatabaseAlways

  • DropCreateDatabaseIfModelChanges

  • NullDatabaseInitializer

  • MigrateDatabaseToLatestVersion

これらのメソッドの詳細はMSDNを参照してください。

OracleとSQL Serverではデータベースの定義方法が異なるため、データベースの初期化操作はモデルのすべてのOracleオブジェクトに対して動作します。Oracleデータベースは作成または削除されず、モデルを構成するオブジェクトがこれらの操作のデータベースとみなされます。

Oracle Databaseオブジェクトの作成

クライアント・アプリケーションをサポートするために、ODP.NETは必要なデータベース・オブジェクトを作成して維持します。プロバイダによって作成および維持されるデータベース・オブジェクトは、次のとおりです。

  • Table

  • 表の列

  • 主キー

  • 外部キー

  • 索引

  • 順序

  • トリガー

注意:

順序とトリガーは、ID列をサポートするためにOracle Database 11gリリース2以下で作成できます。

クライアント・アプリケーション・オブジェクトに直接関係付けられるオブジェクト、たとえばアプリケーション・クラスを表す表や、クラス・プロパティを表す表列などの場合、使用されるオブジェクト名はクライアントによって指定される名前です。これらのオブジェクト名は、Oracle Databaseのオブジェクト識別子の長さ制限に従う必要があります。たとえば、Oracle Databaseでクラス名の長さが有効なオブジェクト識別子の長さを超えている場合、オブジェクトの作成時に「ORA-00972: 識別子が長すぎます。」例外が発生します。

残りのオブジェクトについては、指定した名前の長さがデータベース識別子の長さ制限を超える場合、ODP.NETで名前生成アルゴリズムが使用されます。指定した名前の長さがデータベース制限を超えない場合、名前はそのまま使用されます。どの場合でも、識別子の一部として使われている可能性がある大/小文字と特殊文字を維持するために、オブジェクト名は引用識別子として作成されます。

データベース識別子の長さ制限に適合するようにプロバイダで名前が生成された場合、名前はアンダースコア区切りの次の要素で構成されます。

  • 元の名前の部分文字列(最初の文字から)

  • 元の名前から計算した数値の接尾辞

次の例では、クライアント・アプリケーションで単純なPOCOを使用した名前生成アルゴリズムの結果を示します。

public class LongSamplePocoTestClassName
{
  [Key]
  public int Id { get; set; }
 
  [MaxLength(64)]
  public string Name { get; set; }
}

生成される表の主キーのデフォルト名は、次のとおりです。

PK_LongSamplePocoTestClassNames

この名前には31文字含まれている(1バイトを1文字とする)ので、データベース識別子の制限を超えています。書きなおした主キー名は、次のような値になります。

PK_LongSamplePocoTes_730795129

アルゴリズムは、新しい名前が識別子の長さ制限を超えないようにしつつ、元の名前からできるだけ多くの文字を利用するように設計されています。

表名と所有者の制御

データ注釈とEntity Framework Fluent APIを使用することで、表名と表の所有者を制御することができます。たとえば、規則の命名規則に適合するように表名を明示的に設定することも、あるいは必要な場合にはEntity Frameworkで指定される名前を使用することもできます。Tableデータ注釈を使用して、表名と所有者の両方を制御します。Fluent APIを使用する場合は、ToTableメソッドを使用して、DbContextから導出されるクラスのOnModelCreatingオーバーライド内の表名と所有者を制御します。

次の例では、これらの操作を示すために不完全なクラス定義を使用しています。

データ注釈を使用して表名を設定:

[Table("Employee")]
public class Employee

Fluent APIを使用して表名を設定:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<Employee>().ToTable("Employee");
}

データ注釈を使用して表名と所有者を設定:

[Table("Employee ", Schema="TESTUSER")]
public class Employee

Fluent APIを使用して表名と所有者を設定:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<Employee>().ToTable("Employee", "TESTUSER");
}

注意:

上の例のようにデータ注釈またはFluent APIを使用して所有者を設定する場合、名前も設定する必要があります。

デフォルトの表所有者の設定

ユーザー表ごとに表の所有者を設定するかわりに、Entity Framework 6以上では使用するデフォルト所有者を設定することができます。そのためには、DbContextから導出されるクラスのOnModelCreatingオーバーライド内でHasDefaultSchemaメソッドを呼び出します。

たとえば次のコードでは、デフォルトでTESTUSERスキーマ内にすべてのユーザー表が作成されます。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.HasDefaultSchema("TESTUSER");
}

注意:

所有者名は、大/小文字が区別されます。

デフォルト接続ファクトリの使い方

デフォルト接続ファクトリでは、Oracle接続文字列をDbContextコンストラクタに渡すことでODP.NET接続を確立できます。たとえば、ODP.NET管理対象ドライバのデフォルト接続ファクトリを構成するために次のエントリを使用できます。

<defaultConnectionFactory type="Oracle.ManagedDataAccess.EntityFramework.OracleConnectionFactory,
Oracle.ManagedDataAccess.EntityFramework,
Version=6.121.2.0,
Culture=neutral,
PublicKeyToken=89b483f429c47342" />

デフォルト接続ファクトリを使用するときに、アプリケーションはOracle接続文字列を次のようにDbContextベース・コンストラクタに提供します。

public class TestContext : DbContext
{
  public TestContext()
    : base("<connection string>")
  {
  }
}

ここで、<connection string>はODP.NET接続文字列です。これにより、アプリケーションは次のようなコードを使用してデータベースに接続できます。

using (var ctx = new TestContext())
{
  ...
}

その他の情報については、IDbConnectionFactoryインタフェースのMSDNドキュメントを参照してください。

http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.idbconnectionfactory%28v=vs.113%29.aspx