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

目次

概要

.NET Framework 3.5 SP1で追加されたデータベースアクセステクノロジー

概念モデルに対してプログラミング

Entity Frameworkは、インピーダンス・ミスマッチ問題を解決するため、
エンティティを定義し、エンティティ経由でデータベースへアクセスするための手段を提供する技術。

Entity Data Model(EDM)

CSDL、SSDL、および MSL 仕様
http://msdn.microsoft.com/ja-jp/library/vstudio/bb399604.aspx

CSDL

CSDL(Conceptual Schema Definition Language:概念スキーマ定義言語)
概念スキーマ(概念モデル)

MSL

MSL(Mapping Schema Language:マッピング・スキーマ言語)
CSDLとSSDL(モデル間)のマッピング

SSDL

SSDL(Storage Schema Definition Language:ストア・スキーマ定義言語)
ストレージ・スキーマ(ストレージ モデル)

xxx ファースト

モデルファースト

モデル(EDM)からDBMSのスキーマを生成する方法

DBファースト

DBMSのスキーマからモデル(EDM)を生成する方法

コードファースト

CRUD処理

ここでは、「context」がDbContext?を継承したコンテキストを指している。
サンプルプログラム次第で、context, db, dbContextなどの名称が使用される。

仕組み

Entity States

Entityは以下のEntity Statesを持っており、

SaveChanges?()メソッド

SaveChanges?()メソッドを呼び出した際に、
コレを更新系SQLに変えて実行すると言う、ある種、
RowState? + TableAdapter的な仕組みで動作している。

参照系

LINQは遅延評価

LINQは遅延評価なので、結果が必要になるまではSql文が発行されない。

ToArray()メソッドや、Load()メソッドを使うと、
即時実行されて結果をメモリに起こす事ができる。

オブジェクト参照

オブジェクト参照によりSQLが実行される。

using (var context = new XXXXXContext())
{
    foreach (var YYYYY in context.YYYYYs)
    {
        Console.WriteLine(YYYYY.Name);
    }
}

単一要素取得のLINQメソッド

LINQ to Object

以下の様な感じ。

詳しくは、LINQ to Objectを参照。

LINQ to Entities

以下の様な感じ。

context.YYYYYs.Where(x => x.Id == "1");
context.YYYYYs.Where(x => x.Name == "hogehoge").ToArray();

詳しくは、次章を参照。

注意

全体的に実行されるSQLがブラックボックスで性能を意識し難い。

更新系

Insert

using (var context = new XXXXXContext())
{
    // YYYYY Entity の Statesが
    // Unchanged状態→Added状態へ。
    context.YYYYYs.Add(new YYYYY
    {
        プロパティ名1 = 値1,
        プロパティ名2 = 値2,
    });

    // SaveChanges→Added状態の
    // YYYYY EntityがInsert文に替えられる。
    context.SaveChanges();
}

Update

using (var context = new XXXXXContext())
{
    var yyyyy = context.YYYYYs.Single(x => x.Name == "hogehoge");
    yyyyy.Name = "Aiueo";
    context.SaveChanges();
}

Delete

LINQ to Entities

LINQ to Entities, QueryBuilder?, Entity SQL

外部スキーマ云々的なトピック

JOINのサポート

JOINの使用

JOINを使用しない内部結合

集計処理のサポート

性能問題

全体的に、

から

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

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

という問題がある。

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

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

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

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

ToArray?()メソッド

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

var YYYYYs = context.YYYYYs.ToArray();

Load()メソッド

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

context.YYYYYs.Load();

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

LINQ to Object vs LINQ to Entities

処理される場所が異なる

となる。

処理結果が異なる

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

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

トラッキングしない

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

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

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

コードファースト

マイグレーション

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

規約

コードファーストでは規約に基づいて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による規約

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

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

批判

信任投票

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

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

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

スキーマ構造の変更

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

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

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

参考

Entity Framework Core

@IT

MSDN

magazine

blogs


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


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