如何从C#中的字符串创建基于动态lambda的Linq表达式?

时间:2012-04-11 22:24:01

标签: c# linq lambda expression-trees dynamic-linq

我在从字符串创建基于Lambda的Linq表达式时遇到一些困难。以下是使用此示例对象/类的基本情况:

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

基本上我需要转换这样的字符串:

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

进入to predicate / linq表达式:

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(它现在可以作为NuGet包使用,也称为“DynamicQuery”)

1 个答案:

答案 0 :(得分:1)

这里也提出了类似的问题:

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

据我了解,这个“动态查询”实际上是一个框架,用于在不使用lambda表达式的情况下传递Where子句的限制。

这意味着lambda表达式不是动态方法,它们是匿名方法。如果你看一下程序集,你会看到你的lambda表达式被转换成带有任何自由变量作为字段的闭包。该类有一个匹配你的签名的方法,在调用点分配字段变量。

考虑这一点的一个好方法是它意味着你的lambda表达式在编译时由c#编译器解释,并且通过在运行时从这个类实例化一个对象来解析变量。

为了证明这一点,请考虑以下事项:

var myLambda = x => x * x

你会发现这不起作用。这是因为,为了创建相关的类/方法,编译器必须在编译时知道x的类型。

所有这一切都很重要,因为在运行时CLR上不存在lambda表达式的概念(与代码中的形式相同)。看起来像lambda表达式的字符串就是......