BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Entiry Framework Core 2.0がリリース、厳しい批判に対処

Entiry Framework Core 2.0がリリース、厳しい批判に対処

原文(投稿日:2017/08/21)へのリンク

Entity Frameworkにはかねてより毀誉褒貶相半ばする評価がある。溺愛する開発者がいれば、NHibernateやLinkQ-to-SQL、その他さまざまなマイクロORMと否定的に比較するものもいる状況だ。しかしながら、初期のEF Coreに対する印象は総じて悪く、オリジナルのEntity Frameworkを評価した人たちの間にさえ不評が続いている。

SQL生成

一番に挙げられるのは、生成するSQLサポートの貧弱さである。EF Core 2.0になっても、グループ化など基本的なSQL構成が相変わらずサポートされていないのだ。Window Functionなど、高度な機能がORMでサポートされていないのは珍しくないが、“GROUP BY”が扱えないというのは、多くの開発者にとって受け入れられるものではない。

リリースノートの説明には、今回のバージョンでは“SQLに変換可能なパターンが増えているので、これまでのバージョンではクライアント側で評価されていたクエリが、2.0ではそうではなくなっている”、とある。ただし、これらパターンに関してはまだ文書化されていないため、開発者は個々のクエリを十分注意して検証した方がよいだろう。あるいは、クライアント側での評価を無効にすることも可能だ。

Microsoftによると、グループ化のサポートはEF Core 2.1で予定されている。

複合型

Entity Frameworkには複合型(Complex Types)という概念がある。基本的にこれは、親と同じテーブルにマップされる子オブジェクトを作成するためのものだ。用途のひとつとして挙げられるのは、一般的に使用される監査フィールドを通常のデータフィールドから分離するというものだ。

EF Coreは複合型をサポートしないが、代わりに“owned”あるいは“child”型がある。MicrosoftのDiego B Vega氏は、“EF Core 2.0でのowned型は、以前のバージョンのEFがサポートしていたシナリオのスーパーセットをサポートする”、と主張している。ただし構文とデザインが異なるので、複合型モデルの移植にはある程度の調査が必要だ。

遅延ローディング

遅延ローディングはパフォーマンス上の問題(1+Nクエリなど)や実行時エラー(コンテキストの破棄など)につながる可能性があるため、多くの人たちから好ましくないと考えられている。それにも関わらず、Entity Frameworkでは多用されている一般的な機能であり、これなしではORMと呼ぶことはできないと考える人さえいる。そのような人たちにとって、遅延ローディングのサポートがEF Core 2.1に延期されたことは、当然のことながら不満である。

MicrosoftのRowan Miller氏は、当面の対策として、独自の遅延ローディングを開発する方法について説明している。

ディスカッションにひとつのデータポイントを追加すればよいのです。遅延ローディングは2.0では提供されませんが、それを実装する上で基盤となる機能拡張が追加されています。最も大きいのはLife Cycle Hooksです。これを1.1で追加済みのEntityEntry 1.1と組み合わせることで、初歩的な自己処理型の遅延ローディングパターンを実現することが可能になります。

オブジェクトをマテリアル化するためのLife Cycle Hooksは現在、HF Core 2.1の“ストレッチ目標”となっている。

タイプ毎のテーブル (Table Per Type)

TPT(Table Per Type Inheritance)は、ひとつの元レコードから複数のデータベーステーブルへの分割を可能にするものだ。このデザインでは、ひとつの抽象基本クラスがひとつのテーブルに対応し、サブクラスごとに独自のテーブルがある。この方法により、アプリケーションに対してはデータの論理ビューを公開して、データベースの設計をより効率化することが可能になる。

残念ながらTPTには、Entity Frameworkにパフォーマンス上の重大な問題を抱えているという評価がある。User Voiceには次のような苦情が上げられている。

TPTインスタンスでは、サブクラスが増えれば増えるほど、SQL生成に要する時間も長くなり、SQLクエリ自体も複雑になるため、管理不能になります。単純なベースクラス(5ないし6フィールド)と、30程度の簡単なサブクラス(2ないし3のフィールドを追加)でも、SQLの生成(ObjectQuery.ToTraceString())とサーバ上の実行に約2分を要するのです。EFは、ベースクラスの単純なselectクエリに対して、8,.000行近いSQLを生成します。生成されたSQLが異常なほどの副選択、結合、共用の塊であるために、このようなことが起きるのです。空のテーブル(つまりクエリがデータを返さない)でさえ、SQLの生成と実行には相当な時間が必要です。

こういった問題の多くは修正済みだが、EF 6は旧版ライブラリとみなされており、今後の開発は予定されていない。

TPTはEF Coreではまったくサポートされていない。バックログ項目がひとつあるが、実装に向けての具体的な計画はない。この問題の回避には大規模な変更が必要であるため、EFで現在TPTを使用している開発者にとって、これは大きな問題だ。

具象クラス毎のテーブル(Table per Concrete Class)

TPTと密接に関連する機能として、TPC(Table per Concrete Class)がある。これはTPTと同じように、 クラス設計の簡素化のために継承を使用する。しかしデータベース側には、抽象基本クラスを直接的に表現するテーブルは存在しない。対照的に、具象化された(非抽象の)サブクラスはすべて、サブクラス自体とその継承クラスの両方を項目として持つ、それ自身のテーブルで表現されている。

EF Coreでもサポートされていないように、TPCが実際に使用される場面は多くはないようだ。これは、抽象基本クラスを抽象インターフェースで置き換えることで同じ効果を得られる、という事実によるものと考えられる。基本クラスのプロパティを個々の具象クラスにカット・アンド・ペーストする必要があり、面倒ではあるが、間違いを起こすような難しいものではない。

ストアドプロシージャ

もうひとつ不足している機能が、ストアドプロシージャの完全サポートだ。乱用されるきらいはあるものの、ストアドプロシージャはリレーショナルデータベースの最も強力なツールのひとつである。多くのシナリオにおいて、データベース内ですべてのデータを処理する方法は、ネットワーク越しにアプリケーションにデータを転送しようとするよりも、効率面ではるかに優れている。この傾向は、トランザクション内でテーブルがロックされている間に、複数のラウンドトリップが発生するような場合には特に顕著だ。

SQL生成が非常に簡単なので、これは簡単に実装可能な機能だと考えられる。InfoQが実施したDLRを使用したマイクロORMのデモンストレーションでも、200行足らずのコードで実現できていた。現時点では、実行時期が示されないまま、バックログに残っている。

優先順位が低いのは、回避策が存在するためかも知れない。Anuraj P氏が、EF Coreでストアドプロシージャを呼び出す方法を、名前付きパラメータがないなどの問題点とともに具体的に示している。

空間型(Spatial Types)

空間データの操作は、EF Coreではまだサポートされていない。ロードマップには高い優先順位で記載されているが、対象リリースは特定されていない状況だ。

悪いニュースだけではない。本シリーズのパート2では、EF Core 2.0で実現された新機能について説明する予定だ。

 
 

この記事を評価

採用ステージ
スタイル
 
 

この記事に星をつける

おすすめ度
スタイル

BT