「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>Entity Framework]]

* 目次 [#n42003db]
#contents

*概要 [#j5e93d5b]
[[Entity Framework]]を利用する上での懸念をまとめてみた。

*外部スキーマ云々 [#l921da5a]

**JOINのサポート [#xe24f2b1]

***JOINの使用 [#k6b2044c]
-EntityFramework(CodeFirst)でJoinを試してみる : 日曜ゲームクリエータの日記~
http://kazenetu.exblog.jp/19246594/
-[Entity Framework] LINQ で JOIN 句を使用して複数テーブルからデータを取得する: ある SE のつぶやき~
http://fnya.cocolog-nifty.com/blog/2014/01/entity-framew-6.html
-[Entity Framework] LINQ で LEFT JOIN 句を使用して複数テーブルからデータを取得する: ある SE のつぶやき~
http://fnya.cocolog-nifty.com/blog/2014/01/entity-framew-7.html

***JOINを使用しない内部結合 [#u99ee7fa]
-Entity FrameworkでJoinを使わずに内部結合する - Qiita~
http://qiita.com/keidrumfreak/items/f15d36bfdb35ca2dc6b0
-[Entity Framework] LINQ で JOIN 等を使わずに複数テーブルからデータを取得する: ある SE のつぶやき~
http://fnya.cocolog-nifty.com/blog/2014/01/entity-framew-5.html

**集計処理のサポート [#aec2292d]

*性能云々 [#iec49e1b]
全体的に、

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

から

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

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

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

という問題がある。

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

**Iterator的にDBアクセスしてしまう。 [#k7f89864]
以下の様な手段により、処理対象のEntityをメモリに起こしてしまう。

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

 var YYYYYs = context.YYYYYs.ToArray();

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

 context.YYYYYs.Load();

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

***大量データ処理 [#wfbd142f]
ライブラリがいくつかある。(非 MS 製、NuGet からインストール可能)
-zzzprojects/EntityFramework.Extended · GitHub~
https://github.com/zzzprojects/EntityFramework.Extended
-MikaelEliasson/EntityFramework.Utilities · GitHub~
https://github.com/MikaelEliasson/EntityFramework.Utilities


-参考
--Entity Framework でアトミックインクリメント & 一括更新 | C#.NET vs VB.NET~
http://csharpvbcomparer.blogspot.com/2015/04/net-ef-atomic-increment-and-bulk-update.html
--Entity Frameworkでもバルク更新したいよね(・∀・) - うさ☆うさ日記~
http://d.hatena.ne.jp/machi_pon/20120202/1328187399

**[[LINQ to Object>Entity Framework#t2396e97]] vs [[LINQ to Entities>Entity Framework#b48c3a6f]] [#xdb6f7c2]

***処理される場所が異なる [#ca233ef8]
-[[LINQ to Object>Entity Framework#t2396e97]]は、メモリ上での処理
-[[LINQ to Entities>Entity Framework#b48c3a6f]]は、DBMS上での処理

となる。

-基本的には、[[LINQ to Object>Entity Framework#t2396e97]]が高速だが、

-ストレージが必要な大量データ処理になってくると、~
[[LINQ to Entities>Entity Framework#b48c3a6f]]の方が高速になる可能性がある。

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

-以下は、DB側でNameでソート(OrberBy)される。
 context.YYYYYs.OrberBy(x => x.Name).ToArray()

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

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

**トラッキングしない [#l2b0353c]
AsNoTracking()メソッドでCollectionを取得すると、~
[[Entity States>Entity Framework#zd380b94]]のトラッキングをしなくなる。

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

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

*コードファースト云々 [#e2f2f6d2]
-クラス名(+s)がテーブル名にマップされる。
-プロパティ名がカラム名にマップされる。
-主キーはid or クラス名 + id がデフォルト。

-参考
--Entity Framework Code First | densan-labs.net~
http://densan-labs.net/tech/codefirst/index.html

**マイグレーション [#heee7759]
コードファーストのデータモデルクラスの変更をもとに、~
既存のデータを残したままデータベースのテーブルを変更する機能。

-Entity Framework Code First Migrations~
http://msdn.microsoft.com/ja-jp/data/jj591621.aspx

-3. データベースマイグレーション | densan-labs.net~
http://densan-labs.net/tech/codefirst/migration.html

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

***属性 [#p7736f99]
属性による規約

|項番|属性名|説明|h
|1|Table|EntityとTable間のマッピング|
|2|Column|EntityのPropertyとTableのColumn間のマッピング|
|3|ComplexType|Entityの複数のProperty(Properties)とTable間のマッピング&br;&color(red){ComplexTypeの複数のProperty(Properties)は、別のTableに切り出される。};|
|4|Key|EntityのPropertyを対応するTableのPrimaryKeyに設定する。|
|5|Required|EntityのPropertyに対応するTableのColumnをNOT NULLに設定する。&br;&color(red){MVCのModelMetadataとして検証処理に使用される。};|
|6|MaxLength|EntityのPropertyに対応するTableのColumnのデータ長を設定する。&br;&color(red){MVCのModelMetadataとして検証処理に使用される。};|
|7|Index|EntityのPropertyに対応するTableのColumnを使用した非クラスタ化・インデックスを作成する。|
|8|NoMapped|EntityのPropertyをDatabaseにマップしない。|

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

***Fluent API [#z5aeeab8]
Fluent APIによる規約

-Fluent APIとDbContextの機能 - @IT~
http://www.atmarkit.co.jp/fdotnet/ef4basic/ef4codefirst03/ef4codefirst03_01.html

-Entity Framework Fluent API - プロパティと型の構成/マッピング~
https://msdn.microsoft.com/ja-jp/data/jj591617.aspx

***ナビゲーション・プロパティ [#gc07c222]
エンティティ間の関連(アソシエーション)を表す。
-x対一は、オブジェクト参照を使用。
-x対多は、ICollection<T>を使用。

*批判云々 [#j3882416]
-性能と柔軟性が重視されるエンタープライズの領域では、使い難いとの批判も多い模様。
-ツール等のスタンドアロンのプログラム、情報系システムなどのEUCによるRAD開発などにはマッチする可能性もある。

-また、ADO.NETは枯れた技術であるのに対し、Entity Frameworkは進化の余地がある。

--Entity Framework の歴史を振り返る - kendik.net~
http://kendik.hatenablog.com/entry/2013/05/24/033400
--Entity Framework のバージョン履歴~
https://msdn.microsoft.com/ja-jp/data/jj574253.aspx

**信任投票 [#of646cbb]

-ADO .NET Entity Framework Vote of No Confidence~
http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/

-ADO.NET Entity Framework Taking Some Heat~
http://www.infoq.com/news/2008/06/entity-framework-heat

-Is ORM (Linq, Hibernate...) really that useful - Stack Overflow~
http://stackoverflow.com/questions/938524/is-orm-linq-hibernate-really-that-useful

-Entity Framework VS LINQ to SQL VS ADO.NET with stored procedures - Stack Overflow~
http://stackoverflow.com/questions/2698151/entity-framework-vs-linq-to-sql-vs-ado-net-with-stored-procedures

-データベース ファースト 恵みの波紋~
https://ogacha.wordpress.com/tag/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9-%E3%83%95%E3%82%A1%E3%83%BC%E3%82%B9%E3%83%88/

**ORMの問題 [#ta753a43]

***気付き [#n2f1e368]
Entity Frameworkをキャンセルした[[ASP.NET Identity]]の~
[[UserStore>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/Data/UserStore.cs]]を実装して「ORMの問題だな。」と思った点は、

プログラムの

-インターフェイスとなっている親子階層のあるオブジェクト・モデルと、
-ストレージとの同期処理(セーブ・ロード)のタイミングなどが、

実装者にとって「[[難しい。>#x3abdf31]]」ってトコロではないかと思う。

***背景 [#x3abdf31]
-難しさの背景は、

--自分で[[UserStore>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/Data/UserStore.cs]]を実装していてもこの同期は難しい。
---同期処理の仕様を決める必要がある。
---同期処理の仕様を思い出し、~
処理全体との繋がりを理解する必要がある。

--ORMプロダクトでブラックボックス化した場合、
---同期処理の仕様を決める必要は無いが、
---[[同期処理の仕様を調べたり、デバッガでリバースして>Entity Framework の調査#pefceb5c]]、~
処理全体との繋がりを理解する必要がある。

>等と言った点だと思う。

-※

--[[UserStore>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/CommonLibrary/Data/UserStore.cs]]は、MemoryモードとDBMSモードを処理するので、~
Memoryモードの実装の後、DBMSモードを実装しようとしたタイミングでこの難しさに気付く。

--オブジェクトを操作したタイミングで直ちに同期される仕様にすれば、問題はなくなるが、~
実際は、[[性能云々>#iec49e1b]]に書いたように、性能を考慮して適切なタイミングに同期する必要がある。

**エンプラ領域でのミスマッチ [#x151128c]
基幹系システムでは以下の理由でミスマッチと判断されることが多い。

***インピーダンス・ミスマッチ [#me452f18]
概念モデルに対してプログラミングを採用している。
-外部スキーマを使用できないため、論理データ独立性が無い。
-概念スキーマのデータ構造を使用してプログラミングを行う必要がある。

***スキーマ構造の変更 [#g2c01a47]
-DBMSのスキーマからモデル(EDM)を生成する方法を採用している場合、~
スキーマの構造が変わった場合、モデル(EDM)の作り直しが発生する。

-生成されたモデル(EDM)をカスタマイズしていた場合、~
作り直しにより、カスタマイズが破棄されてしまう可能性がある。
--カスタマイズがなければ、概念スキーマ構造の変更を~
モデル(EDM)に同期し、変更に迅速に対応できるとも言える。
--しかし、論理データ独立性が無いため、プログラムの変更は必要になる。

-RAD開発ツールに特有の、保守性の悪さがある。~

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

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

-(※1)Questions about EntityFramework~
https://github.com/OpenTouryoProject/SampleProgram/issues/6

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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS