如何将字符串转换为对应的LINQ表达式树?

24 浏览
0 Comments

如何将字符串转换为对应的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

以下是我目前的想法:

  1. 在ANTLR中实现一种基本的语法,以支持基本的比较和逻辑运算符。我想复制Visual Basic的优先级和一些特性集在这里:http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
  2. 让ANTLR从提供的字符串创建一个合适的AST。
  3. 遍历AST并使用Predicate Builder框架动态创建Func
  4. 根据需要对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包,文档在这里

0
0 Comments

如何将字符串转换为等效的LINQ表达式树?

问题原因:

这个问题的出现是因为需要将一个字符串表示的过滤条件转换为LINQ表达式树,以便对数据进行筛选操作。

解决方法:

以下是将字符串转换为等效的LINQ表达式树的解决方法:

1. 首先,定义一个包含要筛选的数据的列表。在这个例子中,使用了一个名为`testdata`的`List`。

2. 然后,定义一个表示过滤条件的字符串,包括属性名、比较运算符和值。在这个例子中,使用了`"Qty", "<=", "10"`和`"Name", "==", "abc"`两个过滤条件。

3. 接下来,定义一个方法`strToFunc`,用于将字符串转换为LINQ表达式树。该方法接受四个参数:属性名、比较运算符、值和一个可选的表达式树参数。在方法内部,通过反射获取属性信息,并使用`Expression`类构建表达式树。

4. 在`strToFunc`方法中,还定义了`ToExprConstant`和`ApplyFilter`两个辅助方法,用于处理属性值的转换和应用过滤条件。

5. 最后,使用`testdata`列表和`strToFunc`方法构建LINQ表达式树,并将其编译为可执行的委托函数。然后,通过调用`ToList()`方法将筛选后的结果转换为列表,并将其输出。

以上就是将字符串转换为等效的LINQ表达式树的解决方法。

在这个例子中,使用了LinqPad工具进行测试和调试,并使用`Dump()`方法输出结果。同时,还做了一些代码修改以使其能够正确编译和运行。

需要注意的是,这只是一个简单的示例,实际应用中可能需要根据具体需求进行更复杂的处理和改进。

参考链接:[LinqPad](https://www.linqpad.net/)

0
0 Comments

问题的出现原因:

文章中提到了两个库,一个是Dynamic Linq Library,另一个是Flee。作者进行了这两个库的性能比较,发现在给定的表达式下,Flee的执行速度是Dynamic Linq Library的10倍。作者提到了如何使用Flee来编写代码,但是对于如何使用Flee来构建LINQ表达式树并没有提到。

解决方法:

文章中给出了使用Flee的示例代码,但是并没有直接解决如何将字符串转换为等效的LINQ表达式树的问题。因此,文章并没有提供解决方法。

根据文章内容可以得出以下结论:

1. Flee是一个性能较好的库,适用于处理表达式的计算。

2. 文章中给出了使用Flee的示例代码,但是并没有提供如何使用Flee来构建LINQ表达式树的方法。

0
0 Comments

将字符串转换为其等效的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表达式,并对数据进行筛选和操作。

0