2

Linq to SQL を使用した私のアプリケーションでは、ユーザーはテキストを検索できます。検索式の先頭または末尾にアスタリスク (*) を使用できます。コードは次のとおりです。

var search = SearchTextBox.Text.Trim();
bool filterStartsWith = false, filterEndsWith = false;
if (!string.IsNullOrEmpty(search))
{
    filterStartsWith = search.EndsWith("*");
    filterEndsWith = search.StartsWith("*");
    if (filterStartsWith) search = search.Substring(0, search.Length - 1);
    if (filterEndsWith) search = search.Substring(1);

    if (filterStartsWith)
    {
        if (filterEndsWith)
        {
            query = query.Where(item => item.Omschrijving.Contains(search));
        }
        else
        {
            query = query.Where(item => item.Omschrijving.StartsWith(search));
        }
    }
    else
    {
        if (filterEndsWith)
        {
            query = query.Where(item => item.Omschrijving.EndsWith(search));
        }
        else
        {
            query = query.Where(item => item.Omschrijving == search);
        }
    }
}

ただし、この種の検索はより多くの場所で行われるため、これを一般化したいと思います。また、一部のテーブルでは、これは複数の列で発生するはずです。何か案は?

.NET Framework 4.0 で Visual Studio 2010 を使用しています。

4

3 に答える 3

3

これを試すことができます:

static IQueryable<T> WhereColumnContains<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string search)
{
    if (string.IsNullOrWhiteSpace(search))
    {
        return source;
    }

    Expression<Func<T, bool>> expression;

    search = search.Trim();

    var filterStartsWith = search.EndsWith("*");
    var filterEndsWith = search.StartsWith("*");

    if (filterEndsWith) search = search.Substring(1);

    if (filterStartsWith)
    {
        search = search.Substring(0, search.Length - 1);

        if (filterEndsWith)
        {
            var parameter = Expression.Parameter(typeof(T), "parameter");

            expression = Expression.Lambda<Func<T, bool>>(
                Expression.Call(Expression.Invoke(selector, parameter), typeof(string).GetMethod("Contains", new[] { typeof(string) }), Expression.Constant(search)),
                parameter);
        }
        else
        {
            var parameter = Expression.Parameter(typeof(T), "parameter");

            expression = Expression.Lambda<Func<T, bool>>(
                Expression.Call(Expression.Invoke(selector, parameter), typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), Expression.Constant(search)),
                parameter);
        }
    }
    else
    {
        if (filterEndsWith)
        {
            var parameter = Expression.Parameter(typeof(T), "parameter");

            expression = Expression.Lambda<Func<T, bool>>(
                Expression.Call(Expression.Invoke(selector, parameter), typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), Expression.Constant(search)),
                parameter);
        }
        else
        {
            var parameter = Expression.Parameter(typeof(T), "parameter");

            expression = Expression.Lambda<Func<T, bool>>(
                Expression.Equal(Expression.Invoke(selector, parameter), Expression.Constant(search)),
                parameter);
        }
    }

    return source.Where(expression);
}

次のように呼び出します。

query = query.WhereColumnContains(item => item.Omschrijving, search);
于 2013-10-29T11:56:42.397 に答える
0

戦略パターンを使用できます。「search」値に基づいて「bool CanHandle(search)」メソッドを使用した 4 つの戦略があり、ファクトリーは戦略のリストを作成し、プログラムは単に新しいファクトリーを作成し、メソッドを呼び出すクライアントを呼び出します。 CanHandleメソッドで見つけた正しい戦略を実行し、クエリ値を返す「BuildQuery(search)」。

http://en.wikipedia.org/wiki/Strategy_pattern

于 2013-10-29T09:59:04.020 に答える