セッション 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 アンケートにご協力ください。
© Copyright 2025 ExpyDoc