SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Visual StudioでDB連携も簡単プログラミング ~知っておきたいLINQメソッド式&ラムダ式

DB開発でありがちな悩みを解決! Visual Studioと組合せて便利なLINQメソッド式を使ってみよう

Visual StudioでDB連携も簡単プログラミング ~知っておきたいLINQメソッド式&ラムダ式 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

ちょっと複雑な検索をしてみる

 続いて、もう少し複雑なパターンで検索してみましょう。検索画面で多数の検索条件がある場合、「条件Aが指定されていればAで検索、Bが指定されていればさらにBで検索……」といった処理を書くことが良くあります。たとえば「担当者名が入っていたら部分一致検索、価格が入っていたら価格フィールドで検索、両方とも指定されていればAND検索」というパターンを書いてみましょう(リスト6)。

リスト6 複数条件を積み重ねながら検索
private IQueryable<Product> Search(CodeZineSampleContext context, string employeeName, int? price)
{
    IQueryable<Product> query = context.Products; //(1)まずは全件取得
    if (!string.IsNullOrEmpty(employeeName)) //(2)担当者名が指定されていれば
    {
        //(3)担当者名部分一致検索
        query = query.Where(x => x.Employee.Name.Contains(employeeName));
    }
    if (price.HasValue) //(4)価格が指定されていれば
    {
        query = query.Where(x => x.Price == price.Value); //(5)価格で検索
    }
    return query; //クエリを返す
}

 (1)ではまず条件なしで全件をqueryに代入しています。

 (2)、(3)では、担当者名が指定されている場合だけ、Whereメソッドで部分一致検索します。

 (4)、(5)も同様に、価格が指定されている場合だけ、Whereメソッドで価格検索します。

 勘の鋭い方は「あれ? (1)で全件検索してるんだから、その後にWhereメソッドで条件を指定しても意味ないのでは?」と思われたかもしれません。実はLINQは、書いた時点でその処理が実行されるのではなく「実際にクエリ結果が使われる時になって初めてクエリを処理する」という特徴を持っています。したがって、(1)では実際に全件取得が行われるわけではありません。

 そして注目したいのは、両方の検索条件が指定された場合の(3)と(5)です。この場合、Whereメソッドが複数回呼ばれて、いわば積み重ねられることになります。このように、メソッドを積み重ねることを一般にメソッドチェーンと呼びます。JavaScriptライブラリのjQueryなどで多用される手法ですが、LINQメソッド式でも同様にメソッドを繋いでいく(チェーン)ことができます。この積み重ねは何回でも繰り返すことができますので、もっと多くの検索条件が指定された場合でも、Whereメソッドを自由に積み重ねていくことができます。積み重ねられたWhereメソッドは最終的にクエリが使用される時点でSQLに変換され、データベース上で実行されます。

 大量の検索条件を持つ検索メソッドのSQLを手動で書くことを考えたら気が遠くなりますが、LINQであれば必要に応じて指定された条件のみをWhereメソッドで積み重ねていくことで、条件の増減に容易に対応することができます

LINQの他の機能

 ここまでは、LINQメソッド式の解説と言いつつ、Whereメソッドばかりを説明していました。LINQメソッド式ではそれ以外にも、特定のフィールドだけを選択するSelectメソッド、グルーピングするためのOrderByメソッドなどがあります。

Selectメソッド

 Selectメソッドは、テーブルの特定のフィールドを選択するためのメソッドです。Selectメソッドを使用しない場合は、テーブルの全フィールドが選択されますが、Selectメソッドを使用することで、特定のフィールドのみを選択することができます。SQLのSELECT文で「*(全フィールドを選択)」を使うか、使用するフィールドのみを指定するかの違いと考えれば良いでしょう。

 リスト7は、Selectメソッドで商品の名前だけを取得するサンプルです。

リスト7 Selectメソッドを使ったサンプル
//Selectメソッドで商品名だけ選択する
var names = context.Products.Where(x => x.Price < 300).Select(x => x.Name);
//コレクションを回して
foreach (var name in names)
{
    //Nameを取り出す
    Console.WriteLine("Name: {0}", name);
}

 Selectメソッドのラムダ式では、取得したいプロパティを指定します。ここでは、Nameプロパティだけを選択しています。戻り値はIQueryable<string>という、文字列のコレクションとなりますので、通常通りforeachで回して処理が可能です。

 複数のフィールドを取得したい場合はリスト8のようになります。

リスト8 Selectメソッドを使って複数のプロパティを取得するサンプル
//Selectメソッドで、NameプロパティとPriceプロパティだけを取り出す
//戻り値はNameプロパティとPriceプロパティを持つ匿名型のコレクション
var namePriceList =
  context.Products.Where(x => x.Price < 300).Select(x => new { x.Name, x.Price });
//コレクションを回して
foreach (var obj in namePriceList)
{
    //NameとPriceを取り出す
    Console.WriteLine("Name: {0}, Price: {1}", obj.Name, obj.Price);
}

 ここでは、Name(商品名)とPrice(価格)プロパティを取り出しています。Selectメソッドのラムダ式の戻り値の「new { x.Name, x.Price }」という見慣れない記法に戸惑うかもしれません。これは、C#の匿名型と呼ばれる機能で、NameとPriceというプロパティを持つクラスをその場で定義しています。匿名型は、何度も使い回すことが無い、使い捨てるようなクラスをわざわざ定義することなく、その場で定義して返すことのできる便利な機能です。

 戻り値はこの匿名型のコレクションとなりますが、匿名型はその名の通り型名を持ちませんので、戻り値はvarキーワードで受ける必要があります。使用する場合にはコレクションを回して、普通にName、Price両プロパティにアクセスできますので、匿名型という新しい機能であっても、それほど恐れる必要はありません。

 Selectメソッドは、テーブルの必要なフィールドだけを取得できる便利なメソッドですが、Entity Frameworkにおいては、エンティティクラスのインスタンスとテーブルのレコードを対応させて考えるのが基本となるため、Selectメソッドを使わないケースも多いです。

 本連載では基本的にSelectメソッドを使わず、レコードの全フィールドを取得してエンティティクラスのインスタンスとして扱う方法を使用します。実アプリケーションにおいては、「ドロップダウンリストの表示名と値だけを取得したい」場合など、レコードをエンティティクラスのインスタンスとして取得する必要が無いケースにSelectメソッドを使う場合があります。

次のページ
まとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Visual StudioでDB連携も簡単プログラミング ~知っておきたいLINQメソッド式&ラムダ式連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 土井 毅(ドイ ツヨシ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8378 2015/01/21 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング