web-dev-qa-db-ja.com

動的LINQ-.NET 4バージョンはありますか?

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

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

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

の代わりに

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

または

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

Visual Studio 2008サンプルで動的LINQについて話しているスコットガスリーによる ブログ投稿 に出会いました。これは私が望むことをするようですが、私の質問は次のとおりです:

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

前もって感謝します!

31
David Hoerster

この機能は本当に便利です。 ADO.net Datatablesにも同様の機能があります。 LinqToSqlにも非常に役立ちます。確かに、強く型付けされたチェックを失うことになりますが、それが肝心なのは、動的検索が必要なことです。あなたが例外を適切に処理するならば、私は本当にそれが持つ価値のある機能だと思います。

機能リクエストMicrosoft Connect に追加することを検討してください。ライブラリはすでに存在しているのかもしれませんが、彼らは公式サポートを追加することを検討するでしょう。機能のリクエストを行う場合は、ここにリンクを投稿して、投票できるようにしてください。 Microsoft Connectには、stackoverflowと同様の投票システムがあります。 LinqtoSql TableUpdateVB.net 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 }
6
user295190

PredicateBuilder をご覧ください。

9
Pero P.

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

4
Jens Mikkelsen

私はそれがマイクロソフトによって「サポートされている」とは思わない-それは部分的に言う公的ライセンスの下でリリースされているようだ:

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

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

1
Adam Rackis