マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

Entity Frameworkを利用する上での懸念をまとめてみた。

外部スキーマ云々

JOINのサポート

JOINの使用

JOINを使用しない内部結合

集計処理のサポート

性能云々

全体的に、

  • contextへのアクセス
  • 呼び出すLINQメソッド

から

  • どういうSQLが実行されるのか?
  • 内部動作はどのようになっているのか?

などがブラックボックス化されているため、
Entity Framework自体の仕様に精通していないと、

ハイパフォーマンスな実装をすることができない。

という問題がある。

検索SQLが検索キーや射影の列名を指定しない

foreachでデータアクセスした場合など、
検索SQLが検索キーや射影の列名を指定しないので性能的に問題になる。

Iterator的にDBアクセスしてしまう。

以下の様な手段により、処理対象のEntityをメモリに起こしてしまう。

ToArray?()メソッド

この場合、ToArray?()メソッドを使って、はじめに結果を確定させる。

var YYYYYs = context.YYYYYs.ToArray();

Load()メソッド

この場合、Load()メソッドを使って、DbContext?内にデータをキャッシュさせる。

context.YYYYYs.Load();

この後、context.YYYYYsにアクセスしてもSQLは実行されない。

大量データ処理

ライブラリがいくつかある。(非 MS 製、NuGet からインストール可能)

LINQ to Object vs LINQ to Entities

処理される場所が異なる

となる。

  • ストレージが必要な大量データ処理になってくると、
    LINQ to Entitiesの方が高速になる可能性がある。

処理結果が異なる

処理される場所だけでなく、処理結果が異なることがある。

  • 以下は、DB側でNameでソート(OrberBy?)される。
    context.YYYYYs.OrberBy(x => x.Name).ToArray()
  • 以下はDBからロードされた後、メモリ上でNameでソート(OrberBy?)される。
    context.YYYYYs.ToArray().OrderBy(x => x.Name)

DBMSの照合順序などの関係により、
処理される場所によって、ソート(OrberBy?)順が異なるためである。

トラッキングしない

AsNoTracking?()メソッドでCollectionを取得すると、
Entity Statesのトラッキングをしなくなる。

var YYYYYs = context.YYYYYs.AsNoTracking().ToArray();

これにより、使用するメモリ量を削減できる。

コードファースト云々

  • クラス名(+s)がテーブル名にマップされる。
  • プロパティ名がカラム名にマップされる。
  • 主キーはid or クラス名 + id がデフォルト。

マイグレーション

コードファーストのデータモデルクラスの変更をもとに、
既存のデータを残したままデータベースのテーブルを変更する機能。

規約

コードファーストでは規約に基づいてEntityとDatabaseを紐付ける。

属性

属性による規約

項番属性名説明
TableEntityとTable間のマッピング
ColumnEntityのPropertyとTableのColumn間のマッピング
ComplexType?Entityの複数のProperty(Properties)とTable間のマッピング
ComplexType?の複数のProperty(Properties)は、別のTableに切り出される。
KeyEntityのPropertyを対応するTableのPrimaryKey?に設定する。
RequiredEntityのPropertyに対応するTableのColumnをNOT NULLに設定する。
MVCのModelMetadata?として検証処理に使用される。
MaxLength?EntityのPropertyに対応するTableのColumnのデータ長を設定する。
MVCのModelMetadata?として検証処理に使用される。
IndexEntityのPropertyに対応するTableのColumnを使用した非クラスタ化・インデックスを作成する。
NoMapped?EntityのPropertyをDatabaseにマップしない。

その他、DbContext?を継承したContextのコンストラクタで接続文字列を決定できる。

Fluent API

Fluent APIによる規約

ナビゲーション・プロパティ

エンティティ間の関連(アソシエーション)を表す。

  • x対一は、オブジェクト参照を使用。
  • x対多は、ICollection<T>を使用。

批判云々

  • 性能と柔軟性が重視されるエンタープライズの領域では、使い難いとの批判も多い模様。
  • ツール等のスタンドアロンのプログラム、情報系システムなどのEUCによるRAD開発などにはマッチする可能性もある。
  • また、ADO.NETは枯れた技術であるのに対し、Entity Frameworkは進化の余地がある。

信任投票

エンプラ領域でのミスマッチ

基幹系システムでは以下の理由でミスマッチと判断されることが多い。

インピーダンス・ミスマッチ

概念モデルに対してプログラミングを採用している。

  • 外部スキーマを使用できないため、論理データ独立性が無い。
  • 概念スキーマのデータ構造を使用してプログラミングを行う必要がある。

スキーマ構造の変更

  • DBMSのスキーマからモデル(EDM)を生成する方法を採用している場合、
    スキーマの構造が変わった場合、モデル(EDM)の作り直しが発生する。
  • 生成されたモデル(EDM)をカスタマイズしていた場合、
    作り直しにより、カスタマイズが破棄されてしまう可能性がある。
    • カスタマイズがなければ、概念スキーマ構造の変更を
      モデル(EDM)に同期し、変更に迅速に対応できるとも言える。
    • しかし、論理データ独立性が無いため、プログラムの変更は必要になる。
  • RAD開発ツールに特有の、保守性の悪さがある。

内部実装とその動作がブラックボックス

SQLが、LINQ to Entityのエンジンに生成される形であり、
また、内部実装とその動作がブラックボックスになっているため(※1)
それらが明確にならないと設計、チューニング、問題分析などが困難。

従って(特に日本の)エンタープライズ・アプリケーションでは敬遠されている。
これは、JavaのJava8でJPAでHibernateでJinqが敬遠されるのと≒。


Tags: :.NET開発, :データアクセス, :ADO.NET, :Entity Framework, 性能?


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-31 (火) 09:40:07 (113d)