3

これはおそらくばかげた質問ですが、ここに行きます。データベースのVARCHAR列から解析された文字列、または任意の文字列から述語<T>を動的に構築できるようにしたいと思います。たとえば、データベースの列に次の文字列が含まれているとします。

return e.SomeStringProperty.Contains("foo");

これらのコード/文字列値は、汎用「e」の可能なプロパティが何であるかを認識し、ブール値を返す必要があることを認識して、データベースに格納されます。次に、魔法のような素晴らしいファンタジーの世界では、次のように、述語が何であるかを知らなくてもコードを実行できます。

string predicateCode = GetCodeFromDatabase();
var allItems = new List<SomeObject>{....};
var filteredItems = allItems.FindAll(delegate(SomeObject e) { predicateCode });

またはラムダ化:

var filteredItems = allItems.FindAll(e => [predicateCode]);

おそらくこれほど単純なことはないでしょうが、おそらくReflection.Emitを使用して、テキストから動的にデリゲートコードを作成し、それをFindAll <T>(またはその他の匿名/拡張)メソッドに渡す方法はありますか?

4

4 に答える 4

1

C#およびVBコンパイラは、.NETFramework内から利用できます。

C#CodeDomプロバイダー

ただし、この方法では、別のアセンブリが作成されることに注意してください(別のAppDomainにある場合にのみアンロードできます)。このアプローチは、必要になるすべての述語を一度にコンパイルできる場合にのみ実行可能です。そうしないと、オーバーヘッドが多すぎます。

System.Reflection.Emitは、CLRのコードを動的に発行するための優れたAPIです。ただし、使用するのは少し面倒で、CILを学ぶ必要があります。

LINQ式ツリーは使いやすいバックエンド(CILへのコンパイル)ですが、独自のパーサーを作成する必要があります。

IronPythonなどのCLR(またはDLR)で実行される「動的言語」の1つをご覧になることをお勧めします。あなたが私に尋ねれば、それはこの機能を実装するための最も効率的な方法です。

于 2009-02-19T20:59:07.247 に答える
1

このすべてを実行する Dynamic Linq プロジェクトをチェックしてください。

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

ユーザーが選択した orderby や where 句などの単純なものに最適

于 2009-02-19T20:35:27.700 に答える
0

間違っていることが証明されない限り、コレクションを検索する方法が制限されているため、動的なlinqを削除しました。

私のフィルターは次のようにする必要があります。注文のリストで、リストをフィルターして、その注文のアイテムのコレクションに「コカ・コーラ」という名前のアイテムのみが含まれるようにします。

したがって、次のような方法になります。orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"))

動的言語クエリでは、それを行う方法が見つからなかったため、から始めましたCodeDomProvicerType動的に構築されたメソッドを含むメソッドを使用して、新しいものを作成しましたFindAll

public static IList Filter(list, searchString)
{
   // this will by dynamically built code
   return orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"));
}

このアセンブリを作成しようとすると、次のようになります。

CompilerResults results = provider.CompileAssemblyFromSource(parameters, sb.ToString());

エラーが発生しました:

Invalid expression term ">"

コンパイラが述語をコンパイルできないのはなぜですか?

于 2009-07-03T09:21:11.447 に答える
0

エミットを使用することは可能ですが、独自のパーサーを作成することになります。

編集

ScottGuのPDC基調講演で、Rubyの評価に似たCLIバージョンの.netフレームワークを使用した機能を示したことを覚えていますが、これを裏付けるURLが見つかりません。私はこれをコミュニティウィキにして、良いリンクを持っている人なら誰でも追加できるようにしています。

于 2009-02-19T20:50:57.090 に答える