31

いくつかの検索ルーチンにLINQを使用したいと考えており、動的なwhere句が必要です。したがって、たとえば、ユーザーが都市で検索したり、州で検索したりする場合は、2つの厳密に型指定されたLINQ式を作成し、ユーザーの検索方法に基づいて適切な式を使用する代わりに、動的なLINQWhere<>呼び出しを使用します。 。

だから私はこれをしたいと思います:

String criteria="p.City='Pittsburgh'";  //or "p.State='PA'"
personData.Where(criteria)

それ以外の

personData.Where(p => p.City=="Pittsburgh");

また

personData.Where(p => p.State=="PA");

VisualStudio2008サンプルのDynamicLINQについて話しているScottGuthrieのブログ投稿に出くわしました。これは私が望むことをしているようですが、私の質問は次のとおりです。

  1. このサンプルライブラリはMicrosoftによってサポートされていますか?
  2. Scott Guthrieの記事は、VS2008(.NET 3.5)に関するものです。.NET 4のより良いオプションはありますか?たぶん、同じこと(または非常に近いこと)を達成する.NET 4でリリースされたものですか?

前もって感謝します!

4

4 に答える 4

10

PredicateBuilderをご覧ください。

于 2011-03-02T04:04:18.743 に答える
6

この機能は本当に便利です。同様の機能がADO​​.net Datatablesに存在します。LinqToSqlにとっても非常に役立ちます。確かに、厳密に型指定されたチェックは失われますが、それが要点です。動的検索が必要です。例外を適切に処理すれば、それは持つ価値のある機能だと本当に思います。

Microsoft Connectに機能要求を追加することを検討してください。ライブラリはすでに存在し、正式なサポートを追加することを検討する可能性があります。機能リクエストを行う場合は、ここにリンクを投稿して、投票できるようにしてください。Microsoft Connect には、stackoverflow に似た投票システムがあります。LinqtoSql TableUpdateVB.net Readonly Interfaces like C#をいくつか提出しました。

このライブラリに問題があったことを覚えています。静的メソッドと関係があると思います。

必要な表現を開発したほうがよいことがわかりました。Ilya Builuk によるこの記事では、カスタム式を示しています。Ilya のフレームワークの良いところは、jqGrid の並べ替えなどの操作を行うときに、多くの定型コードを削除できることです。

式の根底にある概念について学ぶのに非常に役立ちました。

このコードの良いところは、ゲッターにドット演算子を使用できることです。Person.Ageまたは、Demeter に違反したい場合は、複数のゲッターを実行することもできます。

コードは改善できます。追加StartsWithして、文字列操作と他のいくつかの検索操作にのみ許可したと思います。一見の価値はありますが、linq 式を理解するのに大いに役立ちました。

public static IQueryable<T> Where<T>(this IQueryable<T> query, string column, object value, WhereOperation operation)
{
    if (string.IsNullOrEmpty(column))
        return query;

    ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");

    MemberExpression memberAccess = null;
    foreach (var property in column.Split('.'))
        memberAccess = MemberExpression.Property
           (memberAccess ?? (parameter as Expression), property);

    //change param value type
    //necessary to getting bool from string
    ConstantExpression filter = Expression.Constant
        (
            Convert.ChangeType(value, memberAccess.Type)
        );

    //switch operation
    Expression condition = null;
    LambdaExpression lambda = null;
    switch (operation)
    {
        //equal ==
        case WhereOperation.Equal:
            condition = Expression.Equal(memberAccess, filter);
            lambda = Expression.Lambda(condition, parameter);
            break;
        //not equal !=
        case WhereOperation.NotEqual:
            condition = Expression.NotEqual(memberAccess, filter);
            lambda = Expression.Lambda(condition, parameter);
            break;
        //string.Contains()
        case WhereOperation.Contains:
            condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("Contains"),
                Expression.Constant(value));
            lambda = Expression.Lambda(condition, parameter);
            break;
    }


    MethodCallExpression result = Expression.Call(
           typeof(Queryable), "Where",
           new[] { query.ElementType },
           query.Expression,
           lambda);

    return query.Provider.CreateQuery<T>(result);
}

WhereOperation 列挙子:

public enum WhereOperation { Equal, NotEqual, Contains }
于 2011-03-03T00:45:36.013 に答える
5

これで利用できるはずです。NuGet からダウンロードできます: http://www.nuget.org/packages/System.Linq.Dynamic/

于 2014-01-17T12:55:22.710 に答える
1

Microsoftによって「サポート」されているとは思いません。パブリックライセンスの下でリリースされているようです。

(E)ソフトウェアは「現状有姿」でライセンス供与されます。あなたはそれを使用するリスクを負います。寄稿者は、明示的な保証、保証、条件を提供しません。あなたは、このライセンスが変更できないあなたの地域の法律の下で追加の消費者の権利を持っているかもしれません。現地の法律で許可されている範囲で、寄稿者は商品性、特定目的への適合性、および非侵害の黙示の保証を除外します。

2番目の質問では、.NET4バージョンはないと思います。3.5は4.0プロジェクトで正常に動作するはずですが、追加するものはそれほど多くないと思います。私が理解しているように、これは、たまに1回限りの文字列ベースのlinqクエリを実行するための気の利いた小さなライブラリでした。何らかの理由でグリッドを手動で並べ替えていて、問題のプロパティを表す文字列に基づいてコレクションの並べ替え順序を変更する必要があった可能性があります。出来上がり。これに多くの機能を追加するために多くの努力が払われることはないでしょう。

于 2011-03-02T03:49:26.310 に答える