ADO.NET Entity Framework Deep Dive Atsushi Fukui (@afukui) 2013.08.03 Hokuriku.NET Vol.12 in Fukui Agenda 自己紹介 Entity Framework とは DbContext, DbSet<T>, DbQuery<T> Code First, DB First, Model First クエリ - LINQ to Entities 関連エンティティの読み込み エンティティの更新 デタッチ オブジェクト トランザクション 同時実行制御 ビュー、ストアドプロシージャの利用 自己紹介 福井 厚 (ふくい あつし) @afukui 株式会社 アークウェイ プリンシパル コンサルタント 現在、やる気と正義感のある若手社員を絶賛募集中 Microsoft Certified Architect – Solution Certification (2008-) Microsoft MVP – Windows Azure (2005-) Visual Studio User Group 運営委員(2005-) 日本XPユーザーグループ スタッフ(2000-) Entity Framework とは Microsoft の開発した O/R マッパー 概念モデルとストレージモデルのマッピング ADO.NET を利用 プロバイダ モデル LINQ to Entities DbContext, DbSet<T>, DbQuery<T> DbContext データベースの接続、トランザクションの管理 エンテ ィティの変更追跡 DbSet<T> エンティティの集合、エンティティの追加、削除のメソッドを提供 DbQuery<T> クエリ式 IOrderedQueryable<TResult>, IQueryable<TResult>, IEnumerable<TResult>, IOrderedQueryable, IQueryable, IEnumerable, IListSource を継承 AsNoTracking(), Include() Code First, DB First, Model First Code First POCO クラスのエンティティ DbContext 継承クラス データベース、テーブルを自動生成 Enable-Migration DB First Entity Model Wizard DbContext 継承クラス、エンティティ クラスのソースコードをT4テンプ レートから生成 Model First EDM から DDL を生成 Demo Code First Demo //1 Database First Demo データソースからメモリへの読み込み using (var context = new NorthwindEntities()) { //Local プロパティは Context に読み込まれたエンティティを表す Console.WriteLine(context.Orders.Local.Count); //Load メソッドで読み込み var query = context.Orders.Load(); Console.WriteLine(context.Orders.Local.Count); } クエリ - LINQ to Entities using (var context = new NorthwindEntities()) { var q = from c in context.Customers where c.Name.StartsWith("A") orderby c.Name select c; foreach (var customer in q) { Console.WriteLine(customer.Name); } } Extension Methods (Single, First, Take, Skip, Sum …) System.Linq.Querable クラスの拡張メソッド SQL の確認 SQL Server Profiler LINQPad DbQuery<T>.ToString(); using (var context = new ShopEntities()) { var query = from c in context.Customers select c; Console.WriteLine(query.ToString()); } Demo LINQ to Entity //2, 3 関連エンティティ 関連エンティティをロードする方法 Navigation Property public partial class Customer { public Customer() { this.Orders = new HashSet<Order>(); } public string CustomerID { get; set; } public string CompanyName { get; set; } public string ContactName { get; set; } public virtual ICollection<Order> Orders { get; set; } } 関連エンティティの明示的な読み込み Include var q = from c in context.Customers .Include(c => Orders) select c; 関連エンティティを後から読み込み context.Configuration.LazyLoadingEnabled = false; var customer = (from c in context.Customers select c).First(); if (!(context.Entry(customer).Collection(c => c.Orders).IsLoaded)) { context.Entry(customer).Collection( c => c.Orders).Load(); } 遅延ロード context.Configuration.LazyLoadingEnabled = true; Demo 関連エンティティのロード //5,6 Add(), Remove() DbSet<T>.Add メソッド TEntity のコレクションに TEntity を追加 追加したエンティティのステータスは EntityState.Added に変更される context.Entry(customer).State で確認 DbSet<T>.Remove メソッド 対象のエンティティのステータスを EntityState.Deleted に変更される using (var context = new NorthwindEntities()) { var targetProduct = (from p in Products).First(); context.Products.Remove(targetProduct); context.SaveChanges(); } context.ChangeTracker.DetectChanges() //自動変更検知を無効化 context.Configuration.AutoDetectChangesEnabled = false; var customer = context.Customers.First(); customer.Name = "afukui"; Console.WriteLine("Customer State {0} ", context.Entry(customer).State); context.ChangeTracker.DetectChanges(); Console.WriteLine("Customer State {0} ", context.Entry(customer).State); エンティティのアタッチ public void SaveCustomer(Customer customer) { using (ver context = new NorthwindEntities()) { context.Customers.Attach(customer); context.Entry(customer).State = EntityState.Modified; context.SaveChanges(); } } Demo その他いろいろ //7,8,9,10 トランザクション SaveChanges メソッド内でローカル トランザクションを自動的に 実行 同時実行制御 同時実行モードを Fixed に変更 データソースが SQL Server の場合はタイム スタンプ列を利用する方法が一番簡単 ビュー、ストアドプロシージャの利用 ビューはテーブル同様にモデルにマップ可能 プライマリキーとなるユニークな列が必要 ストアド プロシージャは DbContext 派生クラスの関数としてマッ プされる Q&A ご質問をどうぞ ご清聴ありがとうございました
© Copyright 2025 ExpyDoc