LINQ(リンク)の基礎知識特集:C#プログラマーのためのLINQ超入門(前編)(2/4 ページ)

» 2008年03月25日 00時00分 公開
[遠藤孝信,デジタルアドバンテージ]

■LINQによるデータベースへの問い合わせ

 リスト1と同じ処理をLINQを使って記述すると次のようになります。実行結果はリスト1の場合とまったく同じです。

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();
    }
  }
}

リスト2 LINQによるデータベースの検索
コードの実行方法については次回で解説。

 2個所で、C# 3.0の新機能である「varキーワード」を使ってローカル変数(recordsとr)を宣言していますが、分かりやすいようにvarキーワードを使わずに記述すると次のリスト3のようになります(LINQを使ううえでジェネリック型を避けて通ることはできません。ジェネリックに関しては「特集:C#&VBジェネリック超入門」をご覧ください)。

 なお、varキーワードは、変数の型指定の記述を省略するためのもので、変数に代入される値の型が右辺から分かる(確実に推測できる)場合には、「var <変数名> = ……」と宣言するだけでコンパイラが自動的に変数の型を設定してくれる便利な機能です。

using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // NorthWindDataContextクラスはVS 2008により自動生成
      NorthWindDataContext dc = new NorthWindDataContext();

      // LINQによる問い合わせ
      IEnumerable<Orders> records =
            from n in dc.Orders
            where n.ShipCountry == "Norway"
            select n;

      // 問い合わせ結果の表示
      foreach (Orders r in records)
      {
        Console.WriteLine("{0}, {1}, {2}, {3}",
          r.OrderID, r.EmployeeID, r.OrderDate, r.ShipCountry);
      }
      Console.ReadLine();
    }
  }
}

リスト3 LINQによるデータベースの検索(varキーワード不使用版)
太字部分はリスト2からの変更個所。

 先頭の行でインスタンス化を行っているNorthWindDataContextクラスは、VS 2008の新機能の1つである「O/Rデザイナ」で作成したクラスです、これはO/Rデザイナの画面にテーブル項目をドラッグ&ドロップするだけで自動生成させることができるのですが、VS 2008でこのリスト2およびリスト3のコードを実行するまでの手順については次回の後編で解説します(本稿の最後では、フリーのツールを使ってOrdersテーブルに対してクエリを実行する方法を示しています)。

 そして、その次の行がLINQによるクエリ(問い合わせ)です(次のリスト4に抜粋)。ここでは読みやすいように改行して3行で記述していますが、1行で書いてもOKです。

from n in dc.Orders
where n.ShipCountry == "Norway"
select n;

リスト4 LINQで記述したクエリ(問い合わせ)

 このクエリの意味は、

『Ordersテーブルから取り出したレコード(ここでは変数nで示す)について、そのShipCountry列の値が「Norway」であるものを抽出する』

というものです(詳しくは後述)。SQL文と比べると記述する順序が完全に逆で、LINQではまずfrom句を書く必要がありますが、全体的にはSQL文と似ていることが分かります(似ているのに微妙に異なるところが実は少々厄介ですが)。

 VS 2008のエディタでは「where n.」と入力したところで、続けて記述可能な候補一覧がIntelliSense機能により表示されますが、次の図のように、これにはOrdersテーブルの列項目が含まれています。

VS 2008のIntelliSense機能による列名の補完

■LINQによるコレクションへの問い合わせ

 LINQの優れている点は、データベース以外に対しても問い合わせが可能なところです。次のコードでは、Ordersテーブルに似せたOrdersクラスを定義し、そのインスタンスの配列に対してLINQを使っています。

using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Orders
    {
      public int OrderID;
      public int EmployeeID;
      public DateTime OrderDate;
      public string ShipCountry;

      // コンストラクタ
      public Orders(int id, int emp, DateTime date, string ship) {
        this.OrderID = id;
        this.EmployeeID = emp;
        this.OrderDate = date;
        this.ShipCountry = ship;
      }
    }

  class Program
  {
    static void Main(string[] args)
    {
      // Ordersオブジェクトの配列
      Orders[] data = new Orders[]
      {
        new Orders(1000, 1, DateTime.Now, "Norway"),
        new Orders(1001, 3, DateTime.Now, "Germany"),
        new Orders(1002, 7, DateTime.Now, "Norway"),
        new Orders(1003, 7, DateTime.Now, "poland"),
      };

      // LINQによる問い合わせ
      IEnumerable<Orders> records =
            from n in data
            where n.ShipCountry == "Norway"
            select n;

      // 問い合わせ結果の表示
      foreach (Orders r in records)
      {
        Console.WriteLine("{0}, {1}, {2}, {3}",
          r.OrderID, r.EmployeeID, r.OrderDate, r.ShipCountry);
      }
      Console.ReadLine();
    }
  }
}

リスト5 LINQによるコレクションの検索

1000, 1, 2008/03/25 3:41:52, Norway
1002, 7, 2008/03/25 3:41:52, Norway

リスト5の実行結果(例)

 クエリ以外のコードはこれまでのC#の機能のみで記述しています。そしてクエリとその結果表示部分はリスト2とほぼ同じになっています。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。