連載:ADO.NET Entity Framework入門

第3回 Entity Frameworkにおけるクエリと更新

WINGSプロジェクト 土井 毅 著/山田 祥寛 監修
2010/08/13
Page1 Page2 Page3

Entity Frameworkでのデータ保存

 前回のサンプル(第2回のリスト3)でも一部触れたが、Entity Frameworkでのデータ保存についてまとめておこう。

 Entity Frameworkにおけるデータの保存は、前回のサンプルのとおり、EDMから生成されたエンティティ・クラスのインスタンスの操作と、ObjectContextクラスのSaveChangesメソッドによって行う。

 リスト5は、SaveChangesメソッドによるデータ保存の例である。前回のサンプルではEntryエンティティのみを保存したが、今回はCategoryエンティティも関連付けて保存している。

using (var container = new AddressBookContainer())
{
  // Entryエンティティを作成
  var entry1 = new Entry()
  {
    Name = "Doi",
    Age = 30,
    TelNo = "03-0000-0000",
    MailAddress = "doi@hogehoge.com"
  };

  // Categoryエンティティを作成
  var category1 = new Category()
  {
    CategoryName = "友達"
  };

  // EntryエンティティにCategoryエンティティを追加
  entry1.Categories.Add(category1);

  // Entryエンティティをデータベースに追加
  container.AddToEntries(entry1);

  // 変更内容を保存
  container.SaveChanges();
}
Using container As New AddressBookContainer()

  ' Entryエンティティを作成
  Dim entry1 As New Entry() With
  {
    .Name = "Doi",
    .Age = 30,
    .TelNo = "03-0000-0000",
    .MailAddress = "doi@hogehoge.com"
  }

  ' Categoryエンティティを作成
  Dim category1 As New Category() With
  {
    .CategoryName = "友達"
  }

  ' EntryエンティティにCategoryエンティティを追加
  entry1.Categories.Add(category1)

  ' Entryエンティティをデータベースに追加
  container.AddToEntries(entry1)

  ' 変更内容を保存
  container.SaveChanges()
End Using
リスト5 SaveChangesメソッドによるデータ保存(上:C#、下:VB)

 ここでは、Entryエンティティと、関連するCategoryエンティティを作成( )した後、Addメソッドを用い、EntryエンティティのCategoriesコレクションにCategoryエンティティを追加している( )。この操作は、データベース上では多対多関係の中間テーブルの行を追加することに相当する。最後にSaveChangesメソッドにより、すべての変更をデータベースに反映させる( )。

 SaveChangesメソッドは複数の保存を処理することができるが、実際には複数の変更に対して複数のSQL文が発行されていることに注意が必要である。従って、大量の更新を行う際には、通常のSQLならばUPDATE文1回で処理できるところを、複数回のSQL処理が必要になるため、パフォーマンスは低下することになる。

 こうした問題に対応するため、Entity Frameworkではデータ更新に関連して以下のような機能が準備されている。

■ストアド・プロシージャの実行

 EDMの設計を行う際に、データベース上のストアド・プロシージャをEDM側にインポートすることが可能である。これにより、Object ServicesおよびEntity Clientから、ストアド・プロシージャを直接呼び出すことができる。詳細は次回解説する。

■ネイティブ(データベース依存の)SQLの実行

 Entity Frameworkでのクエリ実行は、プログラマーがEntity SQLやLINQなどのデータベース非依存のクエリ言語で記述し、それらをEntity Frameworkが使用するデータベース専用のSQL文に変換して実行する、という流れで行われる。

 ただし、特別な用途のためにSQLを用いてデータベース固有の機能を呼び出す必要があるといったニーズにこたえるため、.NET Framework 4からはデータベース依存のSQL文を実行する機能が追加されている。

 これは、ObjectContextクラスのExecuteStoreCommand、ExecuteStoreQuery両メソッドを使用することで、保存およびクエリ用のSQL文をデータベースに対して実行することができる。

 特に、ExecuteStoreCommandメソッドではINSERT、UPDATE、DELETEなどのSQL文を直接実行することができる。前述のとおり、現状のEntity Frameworkではデータベースの複数行に対する一括更新処理がサポートされていないため、パフォーマンスを優先させる場合などには有効である。

 リスト6はSQLのDELETE文を、ExecuteStoreCommandメソッドを使って呼び出している例である。

// オブジェクト・コンテキストの生成
using (var container = new AddressBookContainer())
{
  // ネイティブSQLによるデータの削除
  container.ExecuteStoreCommand("DELETE from EntryCategory;");
  container.ExecuteStoreCommand("DELETE from Entries;");
  container.ExecuteStoreCommand("DELETE from Categories;");
}
' オブジェクト・コンテキストの生成
Using container As New AddressBookContainer()

  ' ネイティブSQLによるデータの削除
  container.ExecuteStoreCommand("DELETE from EntryCategory;")
  container.ExecuteStoreCommand("DELETE from Entries;")
  container.ExecuteStoreCommand("DELETE from Categories;")
End Using
リスト6 ExecuteStoreCommandメソッドを使ったネイティブSQLの実行

 ネイティブSQLの実行は便利だが、Entity Frameworkのそもそもの思想である「概念モデルによるプログラミング」とは相反する機能であるため、乱用は避けたい。

まとめ

 Entity Frameworkでの各クエリ方法の違いについてまとめると、以下の表のようになる。

コンポーネント
Entity Client
Object Services
クエリ方法
Entity SQL
Entity SQL
クエリ・ビルダ
LINQ to Entities
アドホック・クエリ
×
結果をエンティティとして取得
×
データ更新 ストアド・プロシージャ実行 SaveChangesメソッド/ネイティブSQL実行/ストアド・プロシージャ実行
表2 Entity Frameworkでのクエリ方法のまとめ

 クエリ結果をエンティティとして取得できるかどうかは、EDMを使ったプログラミングをスムーズに行ううえで大きな要因となる。そのため、基本的なクエリはObject Servicesを利用して行うことをお勧めしたい。また、Visual Studioが提供するIntelliSense機能を使うことで、クエリを構築する際のミスを減らすことができるため、アドホック・クエリが必要でない場合には、LINQ to Entitiesの使用を推奨する。

 一方で、データ更新の際には、記述しやすさとパフォーマンスとのバランスを取る必要がある。基本的にはSaveChangesメソッドによる更新を推奨するが、パフォーマンスが求められる場面では、ストアド・プロシージャやネイティブSQLの実行を検討してほしい。

 さて次回は、データベースからのリバースによるEDMの作成などについて解説する。End of Article

 

 INDEX
  ADO.NET Entity Framework入門
  第3回 Entity Frameworkにおけるクエリと更新
    1.Entity SQLによるクエリ/クエリ・ビルダによるクエリ
    2.LINQ to Entitiesによるクエリ/遅延読み込み
  3.Entity Frameworkでのデータ保存/まとめ
 
インデックス・ページヘ  「ADO.NET Entity Framework入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間