連載:.NET中心会議議事録 第1回 いま使うべき、学ぶべき.NETテクノロジはどれ? デジタルアドバンテージ 一色 政彦2009/11/18 |
|
|
■討論テーマ 3:データ・アクセス
【用語解説】 |
本稿では、「概念データ・モデル」「論理データ・モデル」「物理データ・モデル」という用語を、下記の意味で使用している。なお、スキーマとはデータ構造のこと。 概念データ・モデル:物理的なオブジェクトやリレーショナル・モデルを意識しない、汎用的なデータ・モデル。具体的には、Entity Frameworkの「EDM(Entity Data Model)」や「Entity SQL」がこのレイヤに属する。 |
赤間 データ・アクセスの手法は、主に次の4つに分けられます。
(1)SQL文をベタ書きする手法(ADO.NETのSystem.Data.SqlClient名前空間など)
(2)ウィザードを利用する手法(ADO.NETのテーブルアダプタ(TableAdapter)など)
(3)O/Rマッピング(LINQ to SQLなど)
(4)概念データ・モデルをベースにした手法(Entity Framework/LINQ to Entitiesなど)
遠藤 今回のアンケート結果を見てみると、(3)と(4)は現在、それぞれ3%の利用者しかおらず、まだまだ少ないようです。しかし今後利用すると答えた人は、17%、18%と、けっこういるようです。
データ・アクセス技術の利用状況/利用意向 |
赤間 今後採用すべき技術として、LINQ to SQLやEntity Frameworkの注目度がとても高いことを表しているアンケート結果ですね。
遠藤 SQL文のベタ書きやテーブルアダプタの利用と比べて、LINQ to SQLやEntity Frameworkのパフォーマンスはどうなんでしょうか? SQL文が自動生成されるという点で、場合によっては悪くなるのではないでしょうか?
赤間 性能の話は少し複雑で、場合によります。
例えばLINQ to SQLの場合、T-SQL(Transact-SQL)文を動的に生成する時間がかかるため、パフォーマンスは相対的に悪くなるでしょう。またEntity Framework/LINQ to Entitiesの場合、データベースのデータ(=物理データ・モデル)から概念データ・モデルへの変換作業がありますから、なおさらパフォーマンスは劣化すると思います。
そのような懸念は理解できます。しかし、そうやって増加した処理時間が、アプリケーション全体の処理時間の中でどれくらいの割合を占めているかを考える必要があります。例えば、データ・アクセスにかかる時間がアプリケーション全体の処理時間の1割しかないとしたら、小さな性能改善を求めるよりも、アプリケーションの保守性を優先させて開発技術を選択した方がよいこともあるでしょう。性能の良しあしだけで、開発技術を選択するべきではありません。
八巻 今後はSQL文ベタ書きやテーブルアダプタではなく、LINQ to SQLやEntity Frameworkを使うべきなのでしょうか?
赤間 LINQ to SQLやEntity Frameworkの一番分かりやすいメリットは、リレーションシップをたどったクエリ、いわゆるJOINクエリ(=複数のテーブルを扱うクエリ)が簡単に書けることです。特に業務アプリケーションでは、JOINクエリが必要な場面が多々あります。SQL文ベタ書きやテーブルアダプタでのJOINクエリの記述は比較的面倒なので、開発生産性を低くしてしまうことが多いのです。
これに対して、LINQ to SQLやEntity FrameworkのLINQ to Entitiesではオブジェクトのプロパティをたどるだけであり、参照系が非常に強力です。ですが、更新系は機能が足りない部分がありますので、注意が必要です。
わたしが担当するのは大規模案件ばかりなので、その特殊性を差し引いて次の話を聞いてください。大規模案件では、1つの技術で幅広いケースに対応できることが重視されます。このため、TableAdapter構成ウィザード(=テーブルアダプタの自動生成)によるデータ・アクセス手法を主に活用するように推奨しています。この手法にしておけば、とりあえず単一技術でさまざまなパターンに対応できるからです。
しかし、参照系しかないようなアプリケーションの場合は、開発生産性を重視して、LINQ to SQLやEntity Frameworkを活用するように推奨することも考えられるでしょう。
ここについては、アプリケーションの処理特性を見て、ケース・バイ・ケースで利用するデータ・アクセス技術を決める必要があります。
会場の参加者 LINQ to SQLとLINQ to Entitiesは、基本的にどちらも同じようなことが可能だと理解しています。だとしたら、どちらを使えばよいのでしょうか? 両者間で、できること/できないことの違いを教えてください。
赤間 技術的に見て、この2つの大きな違いは、クエリ文の処理です。LINQ to SQLの場合には、LINQのクエリがダイレクトにリレーショナル・データにマッピング(O/Rマッピング)されます。一方、LINQ to Entities/Entity Frameworkの場合には、LINQのクエリがいったん概念データ・モデルに対してマッピングされたうえで、実際のSQLのクエリに変換されます。概念データ・モデルには、リレーショナル・モデルを前提としているデータベース構造と異なり、複合データ型が扱えるなど、より複雑なデータ・モデルが扱えるという特長があります。そのようなデータ・モデルを扱いたい場合には、LINQ to Entities/Entity Frameworkを採用するとよいでしょう。
ただし現在、マイクロソフトのデータ・アクセス技術の機能強化は、Entity Frameworkを中心に行われています。そういう意味で、LINQ to SQLよりもLINQ to Entities/Entity Frameworkをより重視しておいた方が、今後は有利だと思います。
@IT Insider .NET編集長 遠藤 孝信 |
遠藤 ところで、Entity Frameworkには、LINQ to Entitiesのほかに、Entity SQL(=概念データ・モデルに対する(文字列の)SQL文)というデータ・アクセス手法も用意されています。しかしEntity SQLが実際に必要となることはあるのでしょうか?
赤間 あくまでわたしの見解です。そもそもLINQ to SQLやLINQ to Entitiesは、C#やVB(Visual Basic)の言語構文にひも付いた機能です。一方、SQL言語やEntity SQLは開発言語にひも付かない汎用的な機能です。つまりSQL言語がリレーショナル・データベースに必要なように、Entity SQLもあってしかるべきものです。
新村 CLR(=共通言語ランタイム)上で動作するすべての言語が、LINQという言語機能をサポートしているわけではありません。例えばIronPythonやIronRubyなどの言語ではまだLINQが使えません。そのような言語では、Entity SQLを使う必要があります。
赤間 C#/VB言語のプログラムの場合はLINQ to Entitiesで書く方が楽なので、それらの言語ではEntity SQLではなくLINQ to Entitiesが主に使われていくのでしょうね。
鈴木 特に参照系のデータ・アクセスの場合は、Visual Studio IDEのサポートを考えると、LINQ to SQLやLINQ to Entitiesを使う方が開発生産性は高いです。
遠藤 Visual Studio 2010に搭載予定の次期Entity Frameworkでは、モデル・ファーストによるデータ・モデル作成が実現できます。つまり、まず概念データ・モデルを定義し、それをデータベースにスキーマとして反映できます。これがEntity Frameworkの本来の目的ではないのでしょうか?
赤間 はい、そのとおりだと思います。Entity Frameworkの一番のキモは、Entity Data Modelと呼ばれている、概念データ・モデルにあります。概念データ・モデルは、オブジェクト・モデルでもなく、リレーショナル・モデルでもありません。オブジェクト・モデルやリレーショナル・モデルは論理データ・モデルですが、Entity Data Modelはそれらの上位概念なのです。その上位概念から、オブジェクト・モデルであるクラスや、リレーショナル・モデルであるデータベース・スキーマを作成できることが重要です。オブジェクト・モデルはリレーショナル・モデルに比べて表現力が高いため、クラスと概念データ・モデルが一緒くたにされてしまいがちなのですが、この両者は実は違うものです。
現在のEntity Frameworkバージョン1は、論理データ・モデルであるデータベース・スキーマから、概念データ・モデルを逆生成します。これは本来の姿ではないと、わたしも感じています。本来は、上位概念から論理データ・モデルや物理データ・モデルが生成されるべきです。次期Entity Frameworkバージョン2では、ようやくこれがサポートされるようになります。
しかし現実には、概念データ・モデルからデータ設計を始める企業はそれほど多くないと思います。概念データ・モデルから論理データ・モデルや物理データ・モデルを作成するというのは確かに学術的には正しいのだけれども、「現実の開発現場で通用する手法なのか?」という疑問があります。また、現状のEntity Frameworkの概念データ・モデルには足りない機能があるのも事実です。
会場の参加者 実際の現場では、学術的なアプローチとは逆方向で、データベース・スキーマから概念データ・モデルやクラスを作成していますよね? そういった開発者には、概念データ・モデルから論理データ・モデル/物理データ・モデルを作成するアプローチはまったく受け入れられないのではないでしょうか?
宮崎 確かに、なかなか難しいと思います。最初に論理データ・モデルであるデータベース・スキーマを直接作成してしまうことの方が多いです。そういった現状をかんがみると、概念データ・モデルから論理データ・モデル/物理データ・モデルを作成するという学術的なアプローチは、現場では採用しづらいことが多いのではないかと予想します。
赤間 概念データ・モデルから論理データ・モデルを作成するアプローチには、ほかにも大きな問題があります。既存資産がある場合です。新規開発ならともかく、既存システムに対してモデル・ファーストのアプローチを適用するのは難しいと思います。
実際にモデル・ファーストのアプローチが開発者のスキルとして定着するには、かなり時間が掛かるのではないかと思います。現在のデータベース開発者のスキルは、データベース・スキーマを作成することに長けていますので。これは、WindowsフォームがWPFという上位の開発技術になかなか移行できないという問題に通じるものがあるのかもしれません。
鈴木 RDBMS(=リレーショナル・データベース管理システム)は、これまで30年という長い間、開発者に支持されてきましたが、これから先もしばらくは支持され続けるでしょう。ですから現時点では、まずはしっかりとSQL文が記述でき、データセット(DataSet)やテーブルアダプタを活用できるといったADO.NETのエキスパートになることが大切で、プラス・アルファのスキルとして、LINQ to SQLやEntity Frameworkのようなスキルを身に付け、その場に応じてより開発生産性の高い技術を選択していくことがベストだと思います。
赤間 わたしも同感です。接続型データ・モデルなのか、非接続型データ・モデルなのかさえもよく理解しないでデータ・アクセス処理を実装しているようなコードを現場でよく見掛けます。そういった基礎知識、基礎スキルがないままに、さらに上位の技術を利用するのは、よりリスクが高まると思います。まずはRDBMSとトランザクション設計、それに関係するアプリケーション設計の基礎部分の学習に、十分な力を割いていただきたいです。
マイクロソフト株式会社 鈴木 祐巳 |
鈴木 特にデータセットを上手に利用できるようになることが、大規模案件への対応やパフォーマンス向上を考えたうえでは重要です。
遠藤 ADO.NETのデータセットと、LINQ to SQLやEntity Frameworkのデータコンテキスト(DataContext)は、表面的には、機能や、使い方が非常に似ているように思えます。だとしたら、今後はデータコンテキストが使えれば十分ではないでしょうか?
赤間 率直にいうと、ADO時代の“レコードセット(RecordSet)”の概念をベースに作られているデータセットの完成度は非常に高いと思います。ところが最近の潮流として、Javaにおける「POJO」(Plain Old Java Object)、.NETでは「POCO」(Plain Old CLR Object)というプレイン・オブジェクト(=非常に単純な構造を持ったオブジェクト)でデータを取り扱いたいというニーズが高まっています。しかし、POJOやPOCOには、オブジェクト追跡(Object Tracking)という機能が備わっていません。そのニーズを満たすために登場したテクノロジが、LINQ to SQLやEntity Frameworkのデータコンテキストという機能です。
オブジェクト追跡機能について少し説明すると、データセットは、自身に対して行われた修正情報を自分自身に保持しておく機能を備えていました。ところが、POJOやPOCOは非常に単純なオブジェクトであり、自身がオブジェクト追跡機能を持っていません。このために、POCOの外に修正情報を持たせる必要があります。この変更情報(=変更セット)を保持しているのが、データコンテキストです。
しかし現状のデータコンテキストには、可搬性(=ポータビリティ)を有していないという欠点が指摘されています。例えばスマート・クライアント形式のシステムで、サーバ側でLINQ to SQLにより取得したデータを、クライアントにPOCO形式で渡します。その後、クライアント側でデータを変更してサーバ側に送信するとしましょう。この場合、データセットならオブジェクト内に変更セットがあるので、そのオブジェクトをサーバ/クライアント間で送受信するだけです。しかしデータコンテキストでは、オブジェクトとは別に、変更セットも渡さなければなりません。しかもLINQ to SQLのバージョン1では、変更セットを搬送する方法がありませんでした。この問題は遠からず解決される予定ですが、そこまでしてPOCOにこだわるのか? というところには疑問を感じる面もあります。
確かに、データコンテキストはPOCOのニーズに応えるために必要です。しかし個人的には、POCOよりも、データセットの方が初心者には分かりやすいと思っています。このあたりはジレンマがありますね
八巻 開発者の間ではデータセットの人気はとても高いです。事実、Silverlightでもデータセットのサポートを望む声は大きいようです。
INDEX | ||
[連載] .NET中心会議議事録 | ||
第1回 いま使うべき、学ぶべき.NETテクノロジはどれ? | ||
1.討論テーマ:Windowsアプリケーション | ||
2.討論テーマ:Webアプリケーション | ||
3.討論テーマ:データ・アクセス | ||
4.討論テーマ:開発言語 | ||
「.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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|
- - PR -