如何将字符串转换为其等效的 LINQ 表达式树? [英] How to convert a String to its equivalent LINQ Expression Tree?

查看:34
本文介绍了如何将字符串转换为其等效的 LINQ 表达式树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是原始问题的简化版本.

This is a simplified version of the original problem.

我有一个叫做 Person 的类:

I have a class called Person:

public class Person {
  public string Name { get; set; }
  public int Age { get; set; }
  public int Weight { get; set; }
  public DateTime FavouriteDay { get; set; }
}

...让我们说一个实例:

...and lets say an instance:

var bob = new Person {
  Name = "Bob",
  Age = 30,
  Weight = 213,
  FavouriteDay = '1/1/2000'
}

我想在我最喜欢的文本编辑器中以字符串的形式编写以下内容......

I would like to write the following as a string in my favourite text editor....

(Person.Age > 3 AND Person.Weight > 50) OR Person.Age < 3

我想使用这个字符串和我的对象实例并评估 TRUE 或 FALSE - 即评估对象实例上的 Func.

I would like to take this string and my object instance and evaluate a TRUE or FALSE - i.e. evaluating a Func<Person, bool> on the object instance.

以下是我目前的想法:

  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 实例的谓词
  1. Implement a basic grammar in ANTLR to support basic Comparison and Logical Operators. I am thinking of copying the Visual Basic precedence and some of the featureset here: http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx
  2. Have ANTLR create a suitable AST from a provided string.
  3. Walk the AST and use the Predicate Builder framework to dynamically create the Func<Person, bool>
  4. Evaluate the predicate against an instance of Person as required

我的问题是我完全烤过头了吗?有其他选择吗?

我决定使用动态 Linq 库,特别是 LINQSamples 中提供的动态查询类.

I decided to use the Dynamic Linq Library, specifically the Dynamic Query class provided in the LINQSamples.

代码如下:

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.

Result is of type System.Boolean, and in this instance is TRUE.

非常感谢 Marc Gravell.

Many thanks to Marc Gravell.

包括 System.Linq.Dynamic nuget 包、文档 这里

Include System.Linq.Dynamic nuget package, documentation here

推荐答案

动态 linq 库 在这里有帮助吗?特别是,我认为是一个 Where 子句.如果有必要,把它放在一个列表/数组中只是为了在它上面调用 .Where(string) !即

Would the dynamic linq library help here? In particular, I'm thinking as a Where clause. If necessary, put it inside a list/array just to call .Where(string) on it! i.e.

var people = new List<Person> { person };
int match = people.Where(filter).Any();

如果没有,编写一个解析器(在引擎盖下使用 Expression)并不是很费力 - 我在我的火车通勤中写了一个类似的(虽然我不认为我有源)圣诞节前...

If not, writing a parser (using Expression under the hood) isn't hugely taxing - I wrote one similar (although I don't think I have the source) in my train commute just before xmas...

这篇关于如何将字符串转换为其等效的 LINQ 表达式树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆