.NET Core, Entity Framework CoreでAND検索・OR検索する方法


はじめに

Web アプリケーションでは、複数キーワードの AND 検索・OR 検索をすることが多いと思います。

.NET Core の Entity Framework Core では、この AND 検索・OR 検索を簡単に行うことができます。

その方法をご紹介します。

なお、環境は、Mac (macOS High Sierra 10.13.3) で .NET Core SDK 2.1.4、PostgreSQL 10.3 、Visual Studio Code になります。

データの準備

まず、PostgreSQLで以下の SQL を実行してデータを準備します。

CREATE DATABASE ConsoleTest;

CREATE TABLE Book (
  Id SERIAL PRIMARY KEY,
  Price int,
  Title text
);

INSERT INTO Book (Price, Title) values (2000,'おはようございますこんにちはこんばんは');
INSERT INTO Book (Price, Title) values (1000,'おはようございます');
INSERT INTO Book (Price, Title) values (500,'こんにちは');
INSERT INTO Book (Price, Title) values (800,'こんばんは');

データベース定義の取り込みについては、以下の記事をご確認ください。

string 型を拡張

.NET の拡張メソッドという手法で string 型を拡張します。

拡張メソッドとは、既存のクラスなどに追加でメソッドを追加して拡張する手法です。

詳しくは以下の記事を参照してください。

以下のクラスは、striing 型を ContainsAll で AND 検索、ContainsAny で OR 検索の機能拡張をしています。

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

//(中略)

static class StringExtensions {
    public static bool ContainsAll( this string str , IEnumerable needles ) => str != null ? needles.All( str.Contains ) : false;
    public static bool ContainsAny( this string str , IEnumerable needles ) => str != null ? needles.Any( str.Contains ) : false;

    public static bool ContainsAll( this string str , params string[] needles ) => str.ContainsAll( needles.AsEnumerable() );
    public static bool ContainsAny( this string str , params string[] needles ) => str.ContainsAny( needles.AsEnumerable() );
}

AND 検索・OR 検索の実装

以下はスペース区切りで、複数キーワードを指定した場合の AND 検索・OR 検索の実装サンプルになります。

   //検索文字列
    string searchString ="おはようございます こんにちは";

    //全角スペースを半角スペースに変換
    searchString = searchString.Replace(" ", " ");

    //検索文字列を分割
    string[] searchList = searchString.Split(" ");

    using (var db = new consoletestContext())
    {
        //AND検索
        Console.WriteLine("*** AND検索 ***");
        var booksAnd = db.Book.Where(m => m.Title.ContainsAll(searchList))
                            .OrderBy(m => m.Id)
                            .ToList();
        foreach (var book in booksAnd) {
            Console.WriteLine(book.Title);
        }

        //OR検索
        Console.WriteLine("*** OR検索 ***");
        var booksOr = db.Book.Where(m => m.Title.ContainsAny(searchList))
                    .OrderBy(m => m.Id)
                    .ToList();
        foreach (var book in booksOr) {
            Console.WriteLine(book.Title);
        }

検索の実行

検索の実行結果は以下のようになります。正しく AND 検索・OR 検索できていることが分かります。

$ dotnet run
*** AND検索 ***
おはようございますこんにちはこんばんは
*** OR検索 ***
おはようございますこんにちはこんばんは
おはようございます
こんにちは

おわりに

Entity Framework Core では、AND 検索・OR 検索が簡単に行えることが分かりました。

AND 検索・OR 検索は可変の SQL を組み立てるのが通常であり、SQL インジェクションの脆弱性を作り込みやすいのですが、LINQ を使っているのでその心配もありません。

積極的に使っていきたいですね。

参考サイト