如何将字符串转换为对应的LINQ表达式树?
如何将字符串转换为对应的LINQ表达式树?
这是原问题的简化版本。我有一个名为Person的类:
public class Person { public string Name { get; set; } public int Age { get; set; } public int Weight { get; set; } public DateTime FavouriteDay { get; set; } }
...假设有一个实例:
var bob = new Person { Name = "Bob", Age = 30, Weight = 213, FavouriteDay = '1/1/2000' }
我想在我喜欢的文本编辑器中将以下内容写成字符串....
(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3
我想将这个字符串和我的对象实例一起使用,并评估一个TRUE或FALSE - 也就是在对象实例上评估一个Func
以下是我目前的想法:
- 在ANTLR中实现一种基本的语法,以支持基本的比较和逻辑运算符。我想复制Visual Basic的优先级和一些特性集在这里:http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
- 让ANTLR从提供的字符串创建一个合适的AST。
- 遍历AST并使用Predicate Builder框架动态创建Func
- 根据需要对Person的实例评估谓词
我的问题是我是否过度考虑了这个问题?有没有其他的选择?
编辑:选择的解决方案
我决定使用Dynamic Linq库,具体来说是LINQSamples中提供的Dynamic Query类。
以下是代码:
using System; using System.Linq.Expressions; using System.Linq.Dynamic; namespace ExpressionParser { class Program { public class Person { public string Name { get; set; } public int Age { get; set; } public int Weight { get; set; } public DateTime FavouriteDay { get; set; } } static void Main() { const string exp = @"(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3"; var p = Expression.Parameter(typeof(Person), "Person"); var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, exp); var bob = new Person { Name = "Bob", Age = 30, Weight = 213, FavouriteDay = new DateTime(2000,1,1) }; var result = e.Compile().DynamicInvoke(bob); Console.WriteLine(result); Console.ReadKey(); } } }
结果的类型为System.Boolean,在这个实例中为TRUE。
非常感谢Marc Gravell。
包含System.Linq.Dynamic nuget包,文档在这里。
如何将字符串转换为等效的LINQ表达式树?
问题原因:
这个问题的出现是因为需要将一个字符串表示的过滤条件转换为LINQ表达式树,以便对数据进行筛选操作。
解决方法:
以下是将字符串转换为等效的LINQ表达式树的解决方法:
1. 首先,定义一个包含要筛选的数据的列表。在这个例子中,使用了一个名为`testdata`的`List
2. 然后,定义一个表示过滤条件的字符串,包括属性名、比较运算符和值。在这个例子中,使用了`"Qty", "<=", "10"`和`"Name", "==", "abc"`两个过滤条件。
3. 接下来,定义一个方法`strToFunc
4. 在`strToFunc
5. 最后,使用`testdata`列表和`strToFunc
以上就是将字符串转换为等效的LINQ表达式树的解决方法。
在这个例子中,使用了LinqPad工具进行测试和调试,并使用`Dump()`方法输出结果。同时,还做了一些代码修改以使其能够正确编译和运行。
需要注意的是,这只是一个简单的示例,实际应用中可能需要根据具体需求进行更复杂的处理和改进。
参考链接:[LinqPad](https://www.linqpad.net/)
问题的出现原因:
文章中提到了两个库,一个是Dynamic Linq Library,另一个是Flee。作者进行了这两个库的性能比较,发现在给定的表达式下,Flee的执行速度是Dynamic Linq Library的10倍。作者提到了如何使用Flee来编写代码,但是对于如何使用Flee来构建LINQ表达式树并没有提到。
解决方法:
文章中给出了使用Flee的示例代码,但是并没有直接解决如何将字符串转换为等效的LINQ表达式树的问题。因此,文章并没有提供解决方法。
根据文章内容可以得出以下结论:
1. Flee是一个性能较好的库,适用于处理表达式的计算。
2. 文章中给出了使用Flee的示例代码,但是并没有提供如何使用Flee来构建LINQ表达式树的方法。
将字符串转换为其等效的LINQ表达式树的方法是一个常见的问题。有几种方法可以解决这个问题。一种方法是使用动态LINQ库,它可以帮助我们将字符串转换为LINQ表达式。使用动态LINQ库,我们可以将字符串作为Where子句传递给一个列表或数组,然后调用.Where(string)方法来筛选数据。下面是一个示例代码:
var people = new List{ person }; int match = people.Where(filter).Any();
如果动态LINQ库不能满足需求,我们可以编写一个解析器来将字符串转换为表达式树。我们可以使用Expression类来实现这一点。下面是一个示例代码:
// Lambda expression as data in the form of an expression tree. System.Linq.Expressions.Expression> expr = i => i < 5; // Compile the expression tree into executable code. Func deleg = expr.Compile(); // Invoke the method and print the output. Console.WriteLine("deleg(4) = {0}", deleg(4));
以上代码将一个lambda表达式转换为一个表达式树,并将其编译为可执行代码。通过调用编译后的委托函数,我们可以得到表达式的结果。
,将字符串转换为其等效的LINQ表达式树有多种方法可以选择。我们可以使用动态LINQ库,也可以编写一个解析器来实现这一目标。使用这些方法,我们可以将字符串转换为LINQ表达式,并对数据进行筛选和操作。