2012-04-11 15 views
2

ラムダベースのLinq式を文字列から作成するのが難しいです。ここでは、このサンプルオブジェクト/クラスを使用して、私の基本的なケースである:C#の文字列から動的ラムダベースのLinq式を作成するには?

public class MockClass 
{ 
    public string CreateBy { get; set; } 
} 

基本的に私はこのような文字列を変換する必要があります:/ LINQの式を述語の中へ

string stringToConvert = “x => x.CreateBy.Equals(filter.Value, StringComparison.OrdinalIgnoreCase”; 

System.Linq.Expressions.Expression<Func<T, bool>> or in this example 
System.Linq.Expressions.Expression<Func<MockClass, bool>> 

したがって、以下のWhereメソッド内のLinq式と同等です。

query = query.Where(x => x.CreateBy.Equals(filter.Value, 
StringComparison.OrdinalIgnoreCase)); 

私は以下のヘルパーを使用しようとしましたが、前もって知られていない文字列からlinq式を構築できるようにするために、 : http://www.albahari.com/nutshell/predicatebuilder.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx(それは今だけでなく、「DynamicQuery」と呼ばれるNuGetパッケージとして利用可能です)

+5

なぜ文字列に最初に置いていますか?ユーザーはその式を入力していますか?適切なタイプで保存してください。 –

+0

デベロッパー以外のユーザーは、クエリ文字列に渡された検索構文に類似したクエリ構文を動的に入力しています。膨大な数の型やネストされた型の任意のプロパティまたはサブプロパティが可能な場合は、適切な型を取得するのが少し難しいです。 – jon333

答えて

1

同様の質問がここに頼まれた:

Is there an easy way to parse a (lambda expression) string into an Action delegate?

私が理解しているように、この '動的クエリ'は、実際にはラムダ式を使用せずにWhere節の制限を渡すためのフレームワークです。

ラムダ式は動的メソッドではなく、匿名メソッドです。アセンブリを見てみると、ラムダ式が任意のフリー変数をフィールドとしてクロージャに変換されていることがわかります。クラスにはあなたの署名と一致するメソッドがあり、フィールド変数は呼び出し時点で割り当てられます。

これは、ラムダ式がコンパイル時にc#コンパイラによって解釈され、実行時にこのクラスのオブジェクトをインスタンス化することによって変数が解決されることを意味します。これを実証するために

、次の点を考慮してください

var myLambda = x => x * x 

あなたは、これは動作しませんがわかります。これは、関連するクラス/メソッドを作成するために、コンパイラはコンパイル時にxの型を知っていなければならないからです。

ラムダ式の概念は、実行時に(コード内の同じ形式で)CLRに存在しないため、このすべてが重要です。ラムダ式のように見える文字列は、まさにその文字列です。

+0

これは、ダイナミックLinqライブラリを使用するトップレベルのプロパティで機能しますが、サブプロパティまたはサブコレクションをサブセット化することはできません。 var test = string.Format( "{0} == {1}"、propertyName、value); var e = DynamicExpression.ParseLambda (テスト);私はこれを翻訳するようなものを得ることができたらいいと思う:query = query.Where( x => x.MockClass.SubCollection.Any(y => y.Name.StartsWith(filter.Value))); – jon333

関連する問題