前回の記事ではEF Core 2.0の新機能と、それに対する批判を取り上げた。今回はEF Coreに数多くある、互換性のない変更点(breaking change)について見ていきたい。
EF Core 1.xプロバイダがサポートされない
データベースプロバイダは、SQL ServerやMySQLなど、データベースに固有のSQLを生成するためのものだ。汎用的なOleDBあるいはODBCプロバイダは存在しないので、EFのデータベース対応は、用意された専用のプロバイダによって制限される。
プロバイダ開発を容易にするため、EF Coreは、下位互換性オプションの提供なしにプロバイダAPIを変更した。これはつまり、EF Core 1.0と1.1のプロバイダはEF Core 2.0ではサポートされない、EF Core 2.0 APIを使って書き直す必要がある、という意味だ。
Microsoftによると、“SQL Compact、PostgreSQL、MySQL用のサードパーティ製プロバイダは2.0用にアップデートされる予定”である。これら以外のデータベースを使用している場合、プロバイダの提供者に連絡するようにMicrosoftでは勧めている。
IDbContextFactoryの名称がIDesignTimeDbContextFactoryに変更された
その名前とは裏腹に、IDbContextFactoryクラスは、アプリケーションがDbContextファクトリとして使うためのものではなかった。むしろ、データベース移行スクリプトの生成などのタスクにおいて、DbContextを必要とする設計時ツールのみが使用することを意図していたのだ。
これを明確にするために、IDbContextFactoryは廃止予定とマークされた。ツールではこれに代えて、IDesignTimeDbContextFactoryを呼び出すようになる。
この変更に合わせて、DbContextFactoryOptionsのサポートも廃止された。設計時のコンテキスト生成には不適切だと判断されたためだ。
ロギングおよび診断イベントが変更された
EF Coreのロギングおよび診断は、次のように変更されている。
- ILoggerに送信されるメッセージのイベントIDが2.0で変更され、EF Coreコード全体で一意なものになった。変更されたメッセージは、例えばMVCなどで使用されている構造化ログの標準パターンにも準拠する。
- ロガーのカテゴリも変更された。DbLoggerCategoryを通じてアクセス可能な、既定のカテゴリセットが定義されている。
- DiagnosticSourceイベントが、対応するILoggerメッセージと同じイベントIDを使用するようになった。イベントのペイロードはすべて、EventDataから派生した名詞型(nominal type)である。
このような互換性のない変更点があるものの、Microsoftでは、既存のアプリケーションに対して大きな影響があるとは考えていない。
インメモリデータベースの名称が必須になった
テストパフォーマンスの面で重要な機能は、インメモリデータベースが生成可能なことだ。運用時のアプリケーションのパフォーマンスを完全に反映してはいないが、ビジネスロジックの問題を確認する上で有用であることには違いない。
これまでのEF Coreではグローバルな、 無名のインメモリデータベースがサポートされていたが、このオプションが廃止されて、各インメモリデータベースに名前を付けなければならなくなった。同じインメモリデータベースを複数のコンテキストインスタンスで共有することは、引き続き可能である。
読み取り専用APIが変更された
IsReadOnlyBeforeSave、IsReadOnlyAfterSave、IsStoreOnlyBeforeSaveのサポートが廃止された。いずれもIPropertyインターフェース で公開されていたもので、IPropertyのBeforeSaveBehavior、AfterSaveBehaviorプロパティに置き換えられている。ドキュメントによると、
>(計算列用などで)ValueGenerated.OnAddOrUpdateとマークされたプロパティは、既定の動作として、そのプロパティに現在設定されている値をすべて無視します。これはすなわち、トラッキングされているエンティティで値の設定や変更が行われたかどうかに関係なく、ストア生成値が常に無視される、ということです。この動作は、Before\AfterSaveBehaviorに別の値を設定することで変更可能です。
新たなフィールドが追加されているため、これもまた、IPropertyインターフェース自身の互換性のない変更と見ることができる。
デフォルトの削除動作がClientSetNullになった
EF Coreにはこれまで、オプションのリレーションを含む削除方法として、3つの動作が可能であった。
- Cascade: 依存するエンティティも同時に削除する。削除対象となるエンティティは、コンテキストによってトラッキングされているものに限定されているため、対応するカスケード動作をデータベースにセットアップして、トラッキングされていないデータにも同じアクションが適用されるようにしておく必要がある。データベースの生成にEFを使用した場合は、このカスケード動作がセットアップされている。
- Restrict: 削除操作は依存するエンティティには適用されず、変更されないまま維持される。
- SetNull: 依存するエンティティの外部キープロパティにnullを設定する。この動作は、コンテキストによってトラッキングされているエンティティにのみ適用される。対応するカスケード動作をデータベースにセットアップして、トラッキングされていないデータにも同じアクションが適用されるようにしておく必要がある。データベースの生成にEFを使用した場合は、このカスケード動作がセットアップされている。
ClientSetNullという名称の新たなオプションが追加されて、これがデフォルトになった。
EF Core 2.0では、オプションのリレーションに関するデフォルト動作として、新たにClientSetNull動作が追加されました。この動作は、トラッキングされているエンティティに対するSetNullセマンティクスと、EF Coreで生成されたデータベースを対象とするRestrict動作を持ちます。私たちの経験では、これらは、トラッキングされているエンティティとデータベースにとって最も望ましく、かつ有用な動作です。オプションのリレーションにDeleteBehavior.Restrictが設定されている場合、トラッキングされているエンティティにはそちらが適用されます。
プロバイダの設計時パッケージが統合された
ちょっとした構成整理として、Microsoft.EntityFrameworkCore.Relational.Designパッケージが削除され、その内容がMicrosoft.EntityFrameworkCore.RelationalおよびMicrosoft.EntityFrameworkCore.Designパッケージに組み込まれた。最終的な効果としては、明示的な参照の必要なパッケージがひとつ減ったということだ。
次の記事では、EF Coreのロードマップを見ていく予定である。
この記事を評価
- 編集者評
- 編集長アクション