ここからは、LINQによるデータベースの検索(LINQ to SQL)について解説していきます。LINQ to SQLとはすなわち、LINQのクエリをSQL文に変換する機能です。
前編では、LINQを使ってデータベースを検索するコードのみを示しました(リスト13に再掲します)。このプログラムはNorthWindというデータベースのOrdersテーブルに対して問い合わせを行っています。ここでは、このコードを記述および実行するのに必要な手順を最初から説明していきます。
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// NorthWindDataContextクラスはVS 2008により自動生成
NorthWindDataContext dc = new NorthWindDataContext();
// LINQによる問い合わせ
var records =
from n in dc.Orders
where n.ShipCountry == "Norway"
select n;
// 問い合わせ結果の表示
foreach (var r in records)
{
Console.WriteLine("{0}, {1}, {2}, {3}",
r.OrderID, r.EmployeeID, r.OrderDate, r.ShipCountry);
}
Console.ReadLine();
}
}
}
■LINQ to SQLに必要なVisual Studio 2008の設定
まずVisual Studio 2008(本稿ではProfessional Editionを使用。以下、VS 2008と略)を起動して、コンソール・アプリケーション*2のプロジェクトを新規作成します。
*2 コンソール・アプリケーションとしたのは、プログラムがシンプルになるためです。別にWindowsアプリケーションでもASP.NETアプリケーションでも何でもOKです。
次に、使用するデータベースの設定を行います。NorthWindデータベースのデータベース・ファイルである「NORTHWND.MDF」*3を、エクスプローラからソリューション・エクスプローラ内のプロジェクトの部分へドラッグ&ドロップします。[データソース構成ウィザード]が起動しますが、これはキャンセルします(データベース・サーバに接続する場合にはこの作業は不要です)。
*3 NORTHWND.MDFの入手については「連載:Windowsデータベース・プログラミング 第4回」をご覧ください
続いては、プロジェクトに対して「新しい項目の追加」を行います。テンプレートに「LINQ to SQLクラス」という項目があるので、これを追加します。ファイル名はデータベース名に合わせて「NorthWind」としました。
[追加]ボタンを押すと、「NorthWind.dbml」がプロジェクトに追加され、今度はVS 2008の中央に「オブジェクト・リレーショナル・デザイナ」(以下、O/Rデザイナ)が開きます。
ここでサーバ・エクスプローラを開き、そこからOrdersテーブル(=LINQのクエリで問い合わせを行うテーブル)をO/Rデザイナ上にドラッグ&ドロップします。これによりOrdersテーブルがO/Rデザイナに表示されます(O/Rデザイナについては後述しています)。
以上で設定は完了です。この設定により、次の2つのクラスが「NorthWind.designer.cs」というファイル内に作成されます。
NorthWindDataContextクラスが出来上がったので、リスト13のプログラムが実行できるようになりました(これらのクラスについても後述します)。Program.csにコピー&ペーストして、プログラムを実行してみてください。
■O/RデザイナでデザインするO/Rマッピング
いま利用したO/RデザイナはVS 2008の新機能で、これは「O/Rマッピング」をデザインするためのツールです。では、O/Rマッピングとは何でしょうか。O/Rデザイナの説明の前に、O/Rマッピングについて説明しておきます。
O/Rマッピングは「オブジェクト」と「リレーショナル・データ」をマッピング、つまり対応付ける技術です。ここでリレーショナル・データとは、リレーショナル・データベース*4のテーブルに格納されているレコードと考えればよいでしょう。
*4 もちろんSQL Serverはリレーショナル・データベースです。
NorthWindデータベースの例で説明していきます。
Ordersテーブルに格納されている注文レコードには、その注文を受け付けた従業員のEmployeeIDが含まれています。そして、その従業員の氏名を知りたい場合には、Employeesテーブルの、該当するEmployeeIDを含む従業員レコードから得ることができます(図4)。これはEmployeeIDにより、注文データと従業員データが関連付けられている(テーブル間でリレーションシップが設定されている)ためです。
同じような構造のデータは、もちろんC#でも記述できます。
次の図5のように、例えば「Ordersクラス」と「Employeesクラス」を定義したとすると、OrdersクラスにEmployees型の「担当者プロパティ」を持たせることにより、OrdersオブジェクトとEmployeesオブジェクトを関連付けることができます。
このように考えていくと、データベースの各テーブルに対応したクラスを定義し、データベースから読み込んだレコードの値を代入したインスタンスを作成すれば、データベース上でリレーションシップにより関連付けられたレコードを、オブジェクトとして表現することができます。
これがまさにO/Rマッピングの目的で、O/Rマッピングはデータベースのレコードと(C#の)オブジェクトを関連付け、データベースへのアクセスをオブジェクトの操作に置き換えてしまう仕組みです。これにより、SQL文を書かなくとも、普段から行っているようなオブジェクトの操作の1つとして、データベースがアクセスできてしまうのです。この場合、「レコードの検索=オブジェクトの検索」となるわけですが、ここでLINQによるクエリが使えるわけです。
LINQによるデータベース・アクセスの処理は、次の図のようなイメージになります。
データベースからレコードをごっそり取得し、それをオブジェクトにしてからLINQによるクエリを実行するわけではない点に注意してください。LINQのクエリはSQL文に変換され、その実行結果がオブジェクトにマッピングされます。
Copyright© Digital Advantage Corp. All Rights Reserved.