有没有办法可以从包含代码的字符串中动态定义Predicate主体?

这可能是一个愚蠢的问题,但这里有。 我希望能够从数据库VARCHAR列或任何字符串解析的字符串动态构造谓词。 例如,假设数据库中的列包含以下字符串:

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

这些代码/字符串值将存储在数据库中,知道通用“e”的可能属性是什么,并且知道它们必须返回布尔值。 然后,在一个神奇,美妙,幻想的世界中,代码可以在不知道谓词是什么的情况下执行,例如:

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

或Lambda化:

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

我知道它可能永远不会这么简单,但有没有办法,也许使用Reflection.Emit,从文本动态创建委托代码并将其提供给FindAll (或任何其他匿名/扩展)方法?

C#和VB编译器可从.NET Framework中获得:

C#CodeDom提供程序

但请注意,这样您最终会得到一个单独的程序集(如果它位于单独的AppDomain中,则只能卸载它)。 只有在您可以一次编译所有需要的谓词时,此方法才可行。 否则涉及太多的开销。

System.Reflection.Emit是一个很棒的API,用于动态发送CLR代码。 但是,它使用起来有点麻烦,你必须学习CIL。

LINQ表达式树是一个易于使用的后端(编译到CIL),但您必须编写自己的解析器。

我建议您查看一下在CLR(或DLR)上运行的“动态语言”,例如IronPython 。 如果你问我,这是实现这个function最有效的方法。

查看Dynamic Linq项目它完成所有这些以及更多!

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

非常适合用户选择的orderby或where子句等简单的东西

可以使用emit ,但是你要构建自己的解析器。

编辑

我记得在ScottGu的PDC主题演讲中,他展示了一个使用.net框架的CLI版本的function,类似于Ruby的eval,但我找不到可以证实这一点的URL。 我正在将它变成一个社区维基,这样任何拥有良好链接的人都可以添加它。

我放弃了动态linq,因为它在我想要搜索集合的方式上受到限制,除非你certificate我错了。

我的filter需要是:在订单列表中,过滤列表,以便我只有订单中的订单,该订单包含名称为“coca cola”的项目。

这将产生一个方法: orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"))

在动态linq我没有找到任何方法,所以我开始使用CodeDomProvicer 。 我创建了一个新的Type ,其方法包含我动态构建的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 ">" 

为什么编译器不能编译谓词?