「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>Entity Framework]] --[[Entity Framework の懸念]] --Entity Framework の調査 * 目次 [#g0ccb6ba] #contents *概要 [#hbe936f5] [[Entity Framework の懸念]]に対する調査結果。 *Entity Frameworkのメモリ使用量の例 [#v08f742a] -ユーザー定義のDbContextを生成 -SqlQueryメソッドで最小限のデータを取得 -DbContextへ格納 -DbContextのライフタイムの管理 **ユーザー定義のDbContext [#v4a65b3a] 例えば、ProductContextクラスは -DbContextクラスから派生する必要がある。 -DbSetのプロパティを含める必要がある。 -DbSetプロパティは、コンテキストで指定されたエンティティのコレクションを表す。 public class ProductContext : DbContext { public DbSet<Category> Categories { get; set; } -Entity Framework Designer を使用している場合、~ コンテキストは、Visual Studioのテンプレートによって自動的に生成される。 -コードファーストテクニックを使用している場合は、手動でコンテキストを作成する。 **DbContextのライフタイム [#a56dc3c5] メモリのデータ保持は、DbContextオブジェクト インスタンスのライフタイムと同じ。 以下のように、usingを使うと、ライフタイムは明確になる。 using (ProductContext context = new ProductContext()) { // Perform data access using the context } **SqlQueryメソッド [#u847bf98] using (ProductContext context = new ProductContext()) { // Below code is enumerated using ToList() method. // Stores all records in “myCategories” object (Memory) IList<Category> myCategories = context.Database.SqlQuery<Category>("Select * from Category").ToList(); } *SaveChangesメソッド使用時のコネクションやトランザクション [#h3e7ed87] -各トランザクションのための新しい接続を作成する。 -SaveChangesメソッドが呼び出されたとき内部でトランザクションを維持する。 -一回のSaveChangesメソッドで複数エンティティ更新のトランザクションを維持する。 **Entity Framework 5.0およびそれ以前のバージョン [#o1d1991d] ***TransactionScope [#kbe4e4c3] TransactionScopeを使用してトランザクションを処理する。 using (EntitiesContext context = new EntitiesContext()) { using (TransactionScope scope = new TransactionScope()) { //Code here } } ***手動の制御も可能 [#ia46ee17] ASP.NET MVCでDbContextのトランザクションと~ 独自SQL 処理のトランザクションを同一のスコープにする~ http://blog.makotoishida.com/2012/12/aspnet-mvcdbcontextsql.html **Entity Framework 6.0 [#ye8d1323] トランザクションを維持するために、2つの新しいAPIを導入している。 ***DbContext.Database.BeginTransaction API [#l61d7378] -トランザクションを開始する。 -トランザクションの分離レベルを指定することができる。 -いくつかの操作を組み合わせて、同じトランザクション内で結合することができる。~ -したがって、全てのトランザクションをコミットまたはロールバックすることができる。 using (EntitiesContext context = new EntitiesContext()) { using (var transaction = context.Database.BeginTransaction()) { try { EmployeeMaster employee = new EmployeeMaster(); employee.Code = "A0001"; employee.Name = "Jignesh Trivedi"; employee.DepartmentId = 1; context.Employees.Add(employee); context.SaveChanges(); DepartmentMaster dept = new DepartmentMaster(); dept.Code = "DEP0001"; dept.Name = "Department 1"; context.Departments.Add(dept); context.SaveChanges(); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); } } } ***DbContext.Database.UseTransaction API [#hb4fa611] -Entity Framework外で明記されたトランザクションを使用するDbContextインスタンスを許可する。 -Entity Frameworkで、このAPIを使用し任意の既存トランザクションを使用することができる。 using (SqlConnection con = new SqlConnection("connectionString")) { con.Open(); using (var transaction = con.BeginTransaction()) { // Do something.... //Pass this transaction to Entity Framework.... using (EntitiesContext context = new EntitiesContext(con, false)) { context.Database.UseTransaction(transaction); EmployeeMaster employee = new EmployeeMaster(); employee.Code = "A0001"; employee.Name = "Jignesh Trivedi"; employee.DepartmentId = 1; context.Employees.Add(employee); context.SaveChanges(); } } } *ExecuteSqlCommandメソッドの実行時の挙動 [#pefceb5c] Entity Frameworkで更新処理を実行する場合、~ 基本的には、SaveChangesメソッドを使用する。 **ExecuteSqlCommand実行後、エンティティとDBは不一致状態に陥る [#sb2b27e7] ExecuteSqlCommandメソッドは、 -コンテキスト内のエンティティの内容に関係なく、~ INSERT、UPDATE、DELETEなどのクエリを実行できる。 -このためExecuteSqlCommandメソッドの実行後は、~ エンティティとDBの内容は一致していない。 -従って、エンティティとDBの内容を一致させる必要がある場合、~ コンテキスト内のエンティティをリフレッシュする必要がある。 **エンティティをリフレッシュする方法(エンティティとDBの同期) [#f0619af5] ***エンティティをデタッチし再度問い合わせる。 [#n1f36b05] ((IObjectContextAdapter)context).ObjectContext.Detach(myCategory); ***Refreshメソッドでリフレッシュする。 [#db23b21b] ObjectContext context = ((IObjectContextAdapter)myDbContext).ObjectContext; // Refresh specific Entity object in the context context.Refresh(System.Data.Objects.RefreshMode.StoreWins, myCategory); (OR) // Refresh All Entities in the context. var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c => c.Entity).ToList(); context.Refresh(System.Data.Objects.RefreshMode.StoreWins, refreshableObjects); *Entity Data Model(以下EDM)のベスト・プラクティス [#ia897808] **更新処理 [#b078de8b] -EDMを複数のエンティティに統合した場合、~ 単一のSaveChangesメソッドの呼び出しで容易に複数のエンティティの更新が可能。 -EDMを複数のエンティティに分割した場合、~ SaveChangesメソッドを複数回呼び出す必要があり、接続とトランザクションの明示的な管理が必要。 **EDMのサイズ [#l59b2cc0] DBに、50~100のテーブルが含まれている場合、~ すべてのエンティティを含む1つの大きなEDMを持つことは良い方法ではない。 ***複数エンティティを単一EDMに結合する [#t0194656] 複数エンティティを1つの大きいEDMに集約すると、下記のようないくつかの問題を起こす。 -性能の問題 --メタデータロード時間の性能 --ビュー生成における性能 -雑然とする。 --デザイナー --インテリセンス --CLRネームスペース ***EDMを任意の単位に分割 [#ea8185c6] 上記を回避するため、~ ベスト・プラクティスは任意の単位にEntity Dataモデルを分割する方法である。 *動的SQLを実装する方法 [#m594ecfb] https://github.com/OpenTouryoProject/SampleProgram/issues/3 **System.Linq.Dynamic [#v4ec2bad] **Expression Tree [#k4607bca] **context.Database.SqlQuery [#c5c889a2] *参考 [#l13157a6] **キャッシュの問題 [#d210ceb7] -ef5 Entity Framework cache problems Bruno Câmara~ http://www.bfcamara.com/post/37112709703/ef5-entity-framework-cache-problems **Entity Dataモデルのサイズ [#b5abc14a] -poco - Entity Framework 4 Does it make sense to create a single diagram for all entities - Stack Overflow~ http://stackoverflow.com/questions/3867479/entity-framework-4-does-it-make-sense-to-create-a-single-diagram-for-all-entiti/3868075 -Working With Large Models In Entity Framework – Part 1 - ADO.NET Blog - Site Home - MSDN Blogs~ http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity-framework-part-1.aspx?wa=wsignin1.0 -Working With Large Models In Entity Framework – ADO.NET Blog - Site Home - MSDN Blogs --http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity-framework-part-1.aspx --http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity-framework-part-2.aspx **性能 [#l09d598c] -Tips to improve Entity Framework Performance~ http://www.dotnet-tricks.com/Tutorial/entityframework/J8bO140912-Tips-to-improve-Entity-Framework-Performance.html ---- Tags: [[:.NET開発]], [[:データアクセス]], [[:ADO.NET]], [[:Entity Framework]], [[:性能]]