セッション ID:T4-402

Download Report

Transcript セッション ID:T4-402

セッション ID:T4-402
ADO.NET
Entity Framework
ディープ ダイブ
~ EF 4 アーキテクチャと実践的活用 ~
アバナード株式会社
CTO オフィス
Group Manager/CTO Architect
福井 厚
セッションの目的とゴール
Session Objectives and Takeaways
セッションの目的
ADO.NET Entity Framework をより深くご理
解いただく (入門セッションではありません)
Entity Framework の機能デモ
セッションのゴール
ADO.NET Entity Framework の機能を理解
し、上司、同僚、部下に対して説明できるよう
になる
実際のアプリケーション開発で Entity
Framework の活用を検討し、設計時に十分に
考慮できるようになる
3
アジェンダ
なぜ Entity Framework なのか?
EF4 Quick Start! おさらい
おさらい
多対多のエンティティ モデル
Model To DB と DB To Model
状態管理 予備知識
同時実行制御 (OCC) 予備知識
n層アプリケーションへの対応
パフォーマンスについての考慮点
コード ファースト 発展
4
本題
本題
なぜ Entity Framework なのか?
.NET Framework は、様々なデータ
アクセス テクノロジを提供しています
ADO.NET DataSet
LINQ to SQL
Entity Framework
5
おさらい
DataSet
おさらい
メリット
変更セットを保持、レイヤーを跨ったデータの
更新が容易
デメリット
データベースのスキーマに強く依存
異なるプラットフォームでのデータ交換が困難
変更前と変更後の情報を保持するためサイズが
大きい
6
LINQ To SQL
おさらい
メリット
LINQ のメリットを享受
最適な SQL の自動生成
異なるプラットフォームでのデータ交換が容易
遅延ロードのサポート
デメリット
SQL Server に特化
Table や View と 1対1 マッピングのみサポー
ト
レイヤーをまたがった更新に工夫が必要
7
Entity Framework
おさらい
メリット
LINQ のメリットを享受
オブジェクト指向プログラミングとの親和性
柔軟なテーブル マッピング
異なるプラットフォームでのデータ交換が容易
遅延ロードのサポート
POCO や自己追跡エンティティのサポート
デメリット
現在もまだ進化中
8
EF4 Quick Start!
多対多 エンティティの操作
多対多エンティティ モデル
10
多対多エンティティへの登録
using (var context = new TechEd10Entities()) {
var techedProject = new Project {
Name = "TechEd Project",
Members = {
new Member { Name = "Fukui",
TweetId = "@afukui"},
new Member { Name = "Moriya",
TweetId = "@hmoriya55"}
}
};
context.Projects.AddObject(techedProject);
context.SaveChanges();
}
11
遅延ロード
var q = from p in context.Projects select p;
foreach (var project in q)
{
Console.WriteLine(project.Name);
foreach (var member in project.Members)
{
Console.WriteLine("\t" +
member.Name + " (" + member.TweetId + ")" );
}
}
12
Entity Data Model (EDM) の概念
おさらい
エンティティ型
Entity Data Model でデータ構造を記述するために不可欠な構成
要素
継承をサポート
アソシエーション型
Entity Data Model でリレーションシップを記述するために不可
欠な構成要素
アソシエーションに含まれるエンティティ型を指定する 2 つのア
ソシエーション End がある
アソシエーション End の多重度も指定する必要がある
プロパティ
エンティティ型には、その構造と特性を定義するプロパティが含まれる
プロパティには、プリミティブ データ (文字列、整数、ブール値など) ま
たは構造化データ (複合型) を含めることができる
13
エンティティの継承
おさらい
Table-Per-Type 継承
基本エンティティと派生エンティティでテーブルを分
割
Table-Per-Hierarchy 継承
継承関係にあるエンティティをすべて単一のテーブル
にマッピング
14
Table-Per-Type 継承
15
Table-Per-Hierarchy 継承
16
エンティティの継承の実現方法
おさらい
Table-per-Type 継承
概念スキーマで派生型の BaseType 属性に基本エン
ティティ型を指定
基本エンティティを抽象型として定義
派生型の ID を削除
マッピングの詳細ウィンドウで ID を基本エンティティ
の ID にマップ
Table-per-Hierarchy 継承
概念スキーマで派生型の BaseType 属性に基本エン
ティティ型を指定
マッピングの詳細ウィンドウで「テーブルまたは
ビューの追加」からテーブルを選択
17
自動生成される SQL の一部
(Table-Per-Type 継承の例)
CREATE TABLE [dbo].[Parties] (
[Id] int IDENTITY(1,1) NOT NULL,
[Name] nvarchar(max) NOT NULL
); GO
CREATE TABLE [dbo].[Parties_Organization] (
[Location] nvarchar(max) NOT NULL,
[Id] int NOT NULL
); GO
CREATE TABLE [dbo].[Parties_Person] (
[Age] int NOT NULL,
[Id] int NOT NULL
); GO
18
状態管理
予備知識
Entity Framework は ObjectContext から
継承したコンテキストでエンティティの状
態管理を行っている
ObjectStateEntry
ObjectStateManager によって管理される
EntityState に状態を格納
アタッチされている各オブジェクトに対して作成され
る
デタッチされると、対応する ObjectStateEntry オブ
ジェクトがオブジェクト コンテキストから削除される
19
EntityState の状態
予備知識
状態
説明
Added
新しいオブジェクトがオブジェクト コンテキストに追加されている。
SaveChanges() メソッドは呼び出されていない。変更が保存されると、
オブジェクトの状態は Unchanged に変更される。
Deleted
オブジェクトがオブジェクト コンテキストから削除されている。変更が
保存されると、オブジェクトの状態は Detached に変更される。
Detached
オブジェクトが存在するが追跡されていない。エンティティは、作成され
た直後とオブジェクト コンテキストに追加される直前にこの状態になる。
また、Detach(Object) メソッドを呼び出してコンテキストから削除され
た後、または NoTracking MergeOption を使用して読み込まれる場合に
もこの状態になる。
Modified
オブジェクトのスカラー プロパティのいずれかが変更されている。
SaveChanges メソッドは呼び出されていない。変更追跡プロキシを持た
ない POCO エンティティでは、DetectChanges メソッドが呼び出された
ときに、変更されているプロパティの状態が Modified に変わる。変更が
保存されると、オブジェクトの状態は Unchanged に変わる。
Unchanged
オブジェクトは、コンテキストに読み込まれた後、または最後に
SaveChanges メソッドが呼び出されてから変更されていない。
20
EF4 状態管理
EntityState の確認
EntityState の確認
using (var context = new TechEd10Entities()) {
//オブジェクトの追加、更新処理をここで行う
…
Console.WriteLine(
context.ObjectStateManager.GetObjectStateEntry(
techedProject).State);
}
22
同時実行制御
予備知識
エンティティ内の任意のプロパティの
ConcurrencyMode を “Fixed” にすると
Entity Framework は、変更をデータベー
スに保存する前に、データベース内の変更
をチェックし、既に変更されている場合は
例外を発生させる
楽観的同時実行制御 (OCC)
SQL Server の場合、各テーブルにタイム
スタンプ列を追加して指定すると良い
他のデータベースの場合はトリガーでタイム
スタンプを更新するなどの工夫を
23
EF4 同時実行制御
同時更新時の動作の確認
n層アプリケーションへの対応
本題
アプリケーションの構造がなぜ変化するの
か?
25
アプリケーション構造の変化
26
本題
パッケージの依存関係
27
本題
EF4 によるレイヤー間の転送パター
ン
本題
シンプルなエンティティ
変更セット
自己追跡エンティティ
DTO (データ転送オブジェクト)
28
シンプルなエンティティ
本題
単一エンティティの更新操作など単純な要
件では利用可能
更新前と更新後の値を独自に保持
複雑なオブジェクト グラフの操作には向か
ない
29
変更セット
本題
DataSet で実現している機能
オブジェクトに対する更新の履歴を保持
データベースのスキーマに強く依存
異なるプラットフォームでの相互運用が困
難
30
自己追跡エンティティ
本題
EF4 が T4 テンプレートを提供しているの
で自動生成が可能
コード記述量が少ない
多くの場合、お勧めのパターン
31
DTO
本題
クライアント側とサービス側で変換コード
が必要
必要なコードの記述量が多い
DTO をうまく設計すると受け渡しに必要な
データだけに絞ることができる
不正な更新を防ぐことが可能
32
EF4 による n層パターンの比較
アーキテクチャの良さ
DTO
自己追跡エンティティ
シンプルなエンティティ
変更セット
実装の容易さ
33
本題
自己追跡エンティティ
T4 テンプレートの利用
自己追跡エンティティ (クライアント側)
var svc = new ChannelFactory<ICustomerService>(
binding, address).CreateChannel();
var customers = svc.GetCustomers();
var products = svc.GetProducts();
var customer = customers.Where(
c => c.CustomerID == "ALFKI").FirstOrDefault();
customer.ContactName = "Bill Gates";
customer.Orders.Add(newOrder);
svc.UpdateCustomer(customer);
35
自己追跡エンティティ (サービス側)
using (NorthwindEntities context =
new NorthwindEntities())
{
context.Customers.ApplyChanges(customer);
context.SaveChanges();
}
36
EF4 パフォーマンス
スタートアップ時に実行すること
モデル メタデータのロード
EF クエリ ビューの生成
最初のクエリ実行で行うこと
EF クエリの翻訳
クエリのキャッシング
LINQ クエリの操作
リザルトの型のキャッシング
37
本題
パフォーマンス Tips
CompiledQuery クラス
読み取り専用クエリ
一括読み込み
ストアド プロシージャの実行
38
本題
パフォーマンス Tips
実証実験
CompiledQuery クラス
static readonly Func<Teched10Entities, string,
IQueryable<Project>> myQuery =
CompiledQuery.Compile<Teched10Entities, string,
IQueryable<Project>>(
(ctx, memberName) => from p in ctx.Projects
where p.Members.Any(
m => m.Name == memberName)
orderby p.Name select p);
private static void CompiledQuerySmaple(){
using (var context = new Teched10Entities()){
var projects = myQuery.Invoke(context,
"Atsushi Fukui");
…
40
パフォーマンス Tips
//読み取り専用カーソルの利用
Context.Customers.MergeOption =
MergeOption.NoTracking;
//一括読み込み
Context.ContextOption.LazyLoadEnabled = false;
context.customers.Include("Orderes");
//ストアド プロシージャの利用
context.ExecuteStoreCommand(
"UPDATE T set a = {0}", params);
41
コード ファースト
発展
先にコードを記述して、そこからモデルや
データベース、テーブルを生成する
テスト駆動型開発と組み合わせて、コード
を作りながらモデルを更新していく
初期段階でアジャイルにコードとデータ モ
デルを作っていくときに非常に有効
42
Code First
CTP4 の機能
POCO クラス
public class Book
{
public string ISBN { get; set; }
public string Title { get; set; }
public DateTime FirstPublished { get; set; }
public bool IsFiction { get; set; }
public virtual Publisher Publisher { get; set; }
public virtual Author Author { get; set; }
}
44
DbContext
public class SimpleBookCatalog : DbContext {
public SimpleBookCatalog(DbModel model)
: base(model)
{ }
public
public
public
public
}
45
DbSet<Book> Books { get; set; }
DbSet<Person> People { get; set; }
DbSet<Author> Authors { get; set; }
DbSet<Publisher> Publishers
{ get; set; }
ModelBuilder
var builder = new ModelBuilder();
builder.Configurations.Add(
new BookConfiguration());
builder.Entity<Person>();
builder.Entity<Publisher>().Property(
p => p.Name).IsRequired().HasMaxLength(50);
var model = builder.CreateModel();
46
EntityConfiguration<T>
public class BookConfiguration :
EntityConfiguration<Book>
{
public BookConfiguration()
{
this.HasKey(b => b.ISBN);
this.Property(b => b.Title).IsRequired();
this.HasRequired(b => b.Author).
WithMany(a => a.Books);
}
}
47
エンティティの追加
using (var context = new SimpleBookCatalog(model))
{
var book = new Book {
ISBN = "2222", Title = "Intro to Code First",
FirstPublished = DateTime.Today,
Author = new Author
{ FirstName = “Atsushi”, LastName = "Fukui" },
Publisher = new Publisher { Name = "EF Books" }
};
context.Books.Add(book);
context.SaveChanges();
48
Convention over Configuration
発展
主キー
以下のパターンで主キーを推論
Id または、クラス名 + "Id"
long、int、short の場合は、Identity 列カラムとし
て登録
リレーションシップ
ナビゲーション プロパティが存在する
2 つのクラスがお互いの型をナビゲーション
プロパティとして持っている場合は、1 つの
リレーションとして扱う
49
Convention over Configuration
外部キー
下記の場合、外部キーを登録
子クラス名 + 親クラスの主キー プロパティ名
親クラス名 + 主キー プロパティ名
主キー プロパティ名と同じ名前で同一の型
50
発展
まとめ
必要に応じて、モデルから DB、DB からモ
デルを生成可能
エンティティの継承と SQL テーブルに対す
る柔軟なマッピング
状態の管理と同時実行制御の機能を提供
自己追跡エンティティ用テンプレートが利
用可能
コード ファーストにより、よりアジャイル
に開発が可能
51
関連セッション
T6-401:WCF RIA Services を使った Silverlight 4 アプリケー
ション開発 ~ 迅速性と効率性の追求 ~
T4-303:Open Data Protocol (Odata) と WCF Data Services に
よるサービスの作成
52
リファレンス
n 層アプリケーションのパターン
http://msdn.microsoft.com/ja-jp/magazine/ee321569.aspx
n 層アプリケーションで回避すべきアンチパターン
http://msdn.microsoft.com/ja-jp/magazine/dd882522.aspx
EF4 による n 層アプリケーションの構築
http://msdn.microsoft.com/ja-jp/magazine/ee335715.aspx
ADO.NET team blog (英語)
http://blogs.msdn.com/b/adonet/
53
ご清聴ありがとうございました。
T4-402
アンケートにご協力ください。