ジョイ・オブ・プログラミング:LINQ(後編)

LINQを活用した簡単XMLデータベース・アプリケーション

シグマコンサルティング 菅原 英治
2008/04/22
Page1 Page2


 こんにちはロブです。またお会いしましたね。今日もジョイ・オブ・プログラミングの時間です。

 前編はLINQ to XMLの基礎について紹介しました。今回はいよいよ前編に示したサンプル・アプリケーションの開発について紹介していきます。前編をきちんと読んでいただきLINQの基礎を理解された方には、とても簡単な内容です。

 サンプル・アプリケーションについて思い出すために、もう一度、実行画面を掲載しておきましょう。

サンプル・アプリケーションの実行画面
記録したレストラン情報を検索するレストラン検索アプリケーション。アプリケーションはこちらから、ダウンロードできる。
  [Id]を入力するテキストボックス。入力された値と等しいIdを持つ結果が一覧に表示される。
  [名前]を入力するテキストボックス。入力された値を含む名前の結果が一覧に表示される。
  [住所]を入力するテキストボックス。入力された値を住所の前方一致で検索し、一致する結果が一覧に表示される。
  [点数]を入力するテキストボックス。入力された値以上の得点の結果が一覧に表示される。
  [検索]ボタン。このボタンを押すと検索する。また、のテキストボックスで[Enter]キーを押すことでも検索できる。
  検索結果の一覧。条件に該当する結果が表示される。

サンプル・アプリケーションのソース解説

 まずは、こちらからサンプル・アプリケーションのソースをダウンロードし、任意のフォルダに解凍してください(※これに含まれる「Window1.xaml.cs」を、前編のものから多少修正しましたので、すでにダウンロードされていた方はお手数ですが再ダウンロードをお願いします)。

サンプル・アプリケーションのソース構成

 サンプル・アプリケーションのソースは、次の表1の4つのファイルで構成されています。

ファイル名 内容
Window1.xaml 画面のデザインを定義しています。本稿では特に解説しません
Window1.xaml.cs LINQを利用した検索ロジックが記述されています。本稿で詳しく解説します
Restaurant.cs レストラン情報を定義したクラスです。ID、名前、住所、得点の属性が定義されています
Restaurants.xml 前編のLINQ to XMLの解説でも利用したレストラン情報を記録したXMLファイルです。またList<Restaurant>型のオブジェクトをシリアライズしたものなので、逆にデシリアライズすることができます
表1 サンプル・アプリケーションのソース構成
ここでのシリアライズとは、アプリケーションのオブジェクトをXMLファイルに保存すること。

 それでは、ソースを解説していきます。

XMLファイルを読み込む(オブジェクトのシリアライズ/デシリアライズ)

 サンプル・アプリケーションでのXMLファイルを読み込む方法について解説します。前編でも述べたように、このサンプルでは、LINQ to XMLは利用していません。その代わり、(Window1.xaml.csファイルの)次のコードのようにXmlSerializerクラス(System.Xml.Serialization名前空間)を利用しています。

// 全レストランを取得する
public List<Restaurant> GetRestaurants()
{
  // XMLファイルを開く
  using (StreamReader reader = new StreamReader("Restaurants.xml"))
  {
    // List<Restaurant>型のシリアライザを生成する
    XmlSerializer serializer =
      new XmlSerializer(typeof(List<Restaurant>));

    // XMLファイルからデシリアライズする
    return (List<Restaurant>)serializer.Deserialize(reader);
  }
}
リスト1 全レストラン情報を取得するGetRestaurantsメソッド(Window1.xaml.cs)

 このGetRestaurantsメソッドでは、XMLファイル(Restaurants.xml)からレストランの一覧であるList<Restaurant>型のオブジェクト(Restaurantオブジェクトのリスト)を生成しています。表1でも述べましたが、このXMLファイルは、List<Restaurant>型のオブジェクトからシリアライズされたものです。従って、逆にこのXMLファイルからList<Restaurant>型のオブジェクトを生成すること(=デシリアライズ)もできるのです。

XMLファイル←→List<Restaurant>型のシリアライズ/デシリアライズ

 このようにXmlSerializerクラスを用いる方法では、レストラン情報を定義したRestaurantクラス(Restaurant.csファイル)を用意する面倒があります。しかし、XElementクラス(System.Xml.Linq名前空間)を利用するLINQ to XMLに比べ、XMLから生成するオブジェクトの型を明確に定義できるというメリットがあります。もちろんどちらの方法が優れているということはないでしょう。プログラムは自由です。

LINQを利用した検索ロジック

 次に[検索]ボタンを押したときのLINQを利用した検索ロジックを解説します。次のコードが検索ロジックです。

// レストラン情報を検索する
private void Search()
{
  // 全レストランを取得する
  IEnumerable<Restaurant> result = GetRestaurants();

  // Id条件(等しい
  int id;
  if (int.TryParse(this.textBoxId.Text, out id))
    result = result.Where(r => r.Id == id);

  // 名前条件(含む)
  if (!string.IsNullOrEmpty(this.textBoxName.Text))
    result = result.Where(
      r => r.Name.Contains(this.textBoxName.Text));

  // 住所条件(前方一致)
  if (!string.IsNullOrEmpty(this.textBoxAddress.Text))
    result = result.Where(
      r => r.Address.StartsWith(this.textBoxAddress.Text));
  // 点数条件(以上
  int point;
  if (int.TryParse(this.textBoxPoint.Text, out point))
    result = result.Where(r => r.Point >= point);

  // 検索結果をリストに設定
  this.listView1.ItemsSource = result;
}
リスト2 レストラン情報を検索するSearchメソッド(Window1.xaml.cs)

 この検索ロジックのコードを解説します。まず、GetRestaurantsメソッドを使って全レストランの情報を取得しています。取得した結果は、LINQによって操作できるようにするために、IEnumerable<Restaurant>型のresultと名付けた変数に代入します。

 続いて、Id、名前、住所、点数などの検索条件を設定していきます。ここでは、条件が設定されている場合のみ条件を追加しています。その方法として、resultのWhereメソッドを利用し、その結果を再度resultに代入するという方法を取っています。

 最後に検索結果を一覧に表示するために、listView1コントロールのItemsSource属性にresultを代入します。resultに設定された条件に合致する結果が、一覧に表示されます。

 サンプル・アプリケーションのソースの解説は以上です。Restaurants.xmlをデシリアライズしてList<Restaurant>オブジェクトを生成し、LINQを利用してそのオブジェクトを検索する流れを理解できたでしょうか。


 INDEX
  ジョイ・オブ・プログラミング:LINQ(前編)
  XMLを扱えるLINQ ―LINQ to XML― の基礎を学ぼう
    1.ジョイ・オブ・プログラミングの伝道師「ロブ」
    2.LINQの基礎
    3.LINQ to XMLについて
 
  ジョイ・オブ・プログラミング:LINQ(後編)
  LINQを活用した簡単XMLデータベース・アプリケーション
  1.サンプル・アプリケーションのソース解説
    2.LINQのWhere条件を動的に変更する方法

 ジョイ・オブ・プログラミング


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 記事ランキング

本日 月間