「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。
ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ
私はソフテックへ入社して3年の社員で、主にWindowsアプリケーションの開発に携わっています。
ある案件でPLCとデータベースの通信の中継をするアプリケーションを開発した際に、Entity Frameworkという技術を扱うことがありました。今回のソフテックだよりでは、Entity Frameworkの特徴やメリット・デメリットについて紹介させていただきます。
Entity Frameworkとは、SQL Serverなどのデータソースへのアクセスを実現するADO.NETに追加された機能の1つです。
従来のADO.NETでは、データベースに対して直接プログラムを作成するため、データベースへの接続文字列やSQL文などを直接書く必要があります。
それに対して、Entity Frameworkでは、概念モデルであるEntity Data Model(EDM)に対してプログラムを作成するため、接続文字列やSQL文は自動で生成されたものを使用することが出来ます。
また、Entity Frameworkを使用することで、データベースからテーブルの定義の取得や、ソースコードからデータベースを作成することなどが出来ます。
データベースからデータを取得する際などに、データが格納されているテーブルの列を意識することなく、プロパティのようにデータを扱うことが出来ますので、アプリケーションのコード量を減らし、高い保守性を実現することが出来ます。
Entity Frameworkを使用した開発にはEDMやデータベースの作り方について、以下の表に示すように3つの開発スタイルがあります。3つの開発スタイルはEDMをどうやって作成するか、データベースをどうやって作成するかというのが大きな違いで、実際にデータベースにアクセスする部分のコードは基本的に共通となります。
No. | 開発スタイル | 参照先 | 生成物 | EDM |
---|---|---|---|---|
1 | データベース・ファースト | データベース | EDM | 必要 |
2 | モデル・ファースト | EDM | データベース | 必要 |
3 | コード・ファースト | ソースコード | データベース | 不要 |
表1. Entity Framework各開発スタイル比較
まず、データベースを作成し、データベース構造からEDMを自動生成する手法です。
既にデータベースが作成されている場合に有効です。
図1にサンプルのテーブルの定義を示します。このテーブルから生成したEDMが図2になります。
図1. テーブル定義(データベース・ファースト)
図2. EDM(データベース・ファースト)
まず、EDMを作成し、EDMからデータベースを自動生成する手法です。
まだ、データベースが作成されておらず、モデルでデータベースを管理したい場合に有効です。
作成したEDMのサンプルを図3に示します。このEDMから生成したデータベースのテーブルが図4になります。
図3. EDM(モデル・ファースト)
図4. テーブル定義(モデル・ファースト)
まず、コードでデータ構造を定義し、定義からデータベースを自動生成する手法です。ソースコードのみで完結するため、EDMを作成する必要はありません。
まだ、データベースが作成されておらず、コードでデータベースを管理したい場合に有効です。
以下にデータベースの元になるコードのサンプルを示します。まず、必要なテーブルのクラスを用意し、フィールドとして必要なデータをプロパティとして用意します。また、用意したそれぞれのテーブルをデータベースに結びつけるためのクラスも用意する必要があります。
以下のコードからデータベースを生成すると、図5のようなテーブルが作成されます。
// 作成したTableName1クラスをデータベースと結びつけるクラス
class TestContext : DbContext
{
public DbSet<TableName1> TableNames1 { get; set; }
}
// テーブルデザインの元になるクラス
class TableName1
{
public int Id { get; set; }
public string Name { get; set; }
}
表2. コード・ファーストでのサンプルコード
図5. テーブル定義(コード・ファースト)
従来のADO.NETでの開発と比較して、Entity Frameworkのメリットやデメリットとして感じた点を紹介させていただきます。
No. | 比較ポイント | ADO.NET | Entity Framework |
---|---|---|---|
1 | コード量 | 多い | 少ない |
2 | SQL文発行 | ベタ書き | 自動生成 |
3 | 保守性 | 低い | 高い |
4 | データアクセス速度 | 速い | 遅い |
5 | データ型定義 | なし | あり |
表3. 従来のADO.NETとEntity Frameworkの比較
Entity Frameworkを使用すると、従来のADO.NETに比べてコード量が少なくなります。
データベースから「TableName1」という名前のテーブルを取得し、IDを出力するプログラミングの例として、以下に従来のADO.NETでのプログラミング時のコードとEntity Frameworkを使用したプログラミング時のコードを記載します。 Entity Frameworkを使用する場合、データベースへの接続文字列はエンティティクラスに登録されているため省略できますし、OpenやCloseなども明示的に記述する必要がありません。
テーブルなどのデータの構造についても、EDMと一緒にデータ構造のクラスがあるため、テーブルのフィールド指定時に、インデックスでの指定でなく、プロパティのように指定できます。なお、コード・ファーストの場合はEDMを作成しませんが、ソースコードでテーブルのデータ構造を記述しているため、これをそのまま使用します。
// データベースへの接続文字列取得
SqlConnection sqlConnection = new SqlConnection (
string.Format(
"Server={0};Database={1};User Id={2};Password={3};Connection Timeout={4}",
127.0.0.1, DBName, UserName, Password, 10));
// データベース接続
sqlConnection.Open();
// SQLコマンド
SqlCommand sqlCom = new SqlCommand();
// コマンドの接続設定
sqlCom.Connection = sqlConnection;
// Selectコマンド作成
sqlCom.CommandText = "SELECT * FROM TableName1";
// データテーブル取得
DataTable data = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
adapter.SelectCommand = sqlCom;
adapter.Fill(data);
}
// データベース切断
sqlConnection.Close();
sqlConnection.Dispose();
// ID出力
foreach (DataRow item in data.Rows)
{
Console.WriteLine(item[0/*Index0=ID*/]);
}
表4. ADO.NETのプログラミング
var entities = new Entities(); // ←エンティティクラス
var query = (from t in entities.TableName1 select t).ToList();
// ID出力
foreach (var item in query)
{
Console.WriteLine(item.Id);
}
表5. 概念モデルを使用したプログラミング
従来のADO.NETでSQL文を発行する場合は、表4のプログラミング例の「"SELECT * FROM TableName1"」のようにSQL文をベタ書きすることになります。
Entity Frameworkを使用すると、表5のプログラミング例の「from t in entities.TableName1 select t」のようにLINQ to Entitiesを使用することができます。
LINQとはLanguage Integrated Queryの略で、統合言語クエリとも呼ばれており、配列やコレクションオブジェクト、データベースなどに対して統一された操作でデータを問い合わせるクエリの発行ができます。今回のLINQ to Entitiesは概念モデルに対するクエリの発行をサポートしており、LINQの形式でデータアクセス部分を見やすく記述しつつ、SQL文を内部で発行することが出来ます。
Entity Frameworkを使用すると保守性が向上します。
まず、4.1で紹介したようにコード量が少ないため、変更が容易であるという理由があります。
また、4.2で紹介したLINQ to Entitiesはデータベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースエンジンに対応することが出来ます。私が携わった案件で、初めはデータベースエンジンがOracle DataBaseで、途中でSQL Serverに変更になるということがありましたが、LINQ to Entitiesでクエリを作成していましたので、大きな変更なく修正することが出来ました。
その他にも、テーブル仕様の変更への対応が容易であるという理由もあります。
従来のADO.NETですと、テーブル名が変更されたら直接指定しているテーブル名の部分を変更する必要がありますし、テーブルの列が追加・削除された場合は、列の位置によってはインデックスの指定が変わりますが、コンパイル時にエラーが出ないため、修正のために広い範囲をくまなく確認する必要があります。Entity Frameworkの場合、データベースに接続し、エンティティに登録されているテーブルを更新するだけで基本的には修正は完了するため、非常に容易に対応できます。
データアクセス速度については、Entity Frameworkよりも従来のADO.NETが優れています。データベースから100万件のデータを取得するサンプルアプリケーションを作成し、速度を比較してみたところ、Entity Frameworkでは6.3〜6.4秒程度でしたが、従来のADO.NETでは2.4〜2.5秒程度でした。データ数が少ない場合はあまり差を感じないかもしれませんが、Entity Frameworkでデータを大量に扱う場合は注意が必要です。
Entity Frameworkの場合、EDMに各テーブルのデータ型の定義があるため、コンパイル前の段階で型が正しいかなどが分かります。ただ、EDMがない場合はテーブルが参照できず、プログラミングができません。
従来のADO.NETの場合ですと、コンパイルの段階ではデータの型が分からず、実際に動かしてみるまで動くか分かりません。ただ、テーブル名は直接指定し、列もインデックスでアクセスできるため、データベースが用意されていない状態でもプログラミングができます。
Entity Frameworkで開発することになり、初めは「今までの方法ではダメなのか?」と思いましたが、実際に使用してみると、快適にプログラミングすることができました。特にLINQ to Entitiesがデータアクセスにおいて非常に便利だと感じました。
性能的なメリットは特になく、扱うデータ量等に注意する必要がありますが、開発効率が向上する優れた機能だと思います。
今回紹介した内容がEntity Frameworkを使用する際の参考になれば幸いです。
(Y.O.)
関連ページへのリンク
関連するソフテックだより