如何将字符串转换为其对应的LINQ防爆pression树? [英] How to convert a String to its equivalent LINQ Expression Tree?

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

问题描述

这是原问题的一个简化版本。

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键&LT;创建的对象的人,布尔>

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 precedence和这里的一些功能集的:<一href=\"http://msdn.microsoft.com/en-us/library/fw84t893%28VS.80%29.aspx\">http://msdn.microsoft.com/en-us/library/fw84t893(VS.80).aspx

  2. 让ANTLR创建一个字符串提供一个合适的AST。

  3. 步行的AST,并使用 predicate构建器框架动态创建函数功能&LT;人,布尔>

  4. 评估对人的一个实例predicate要求

  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

我的问题是有我完全overbaked呢?任何替代方案?

我决定使用动态LINQ的图书馆,特别是在LINQSamples提供的动态查询类。

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

code如下:

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 = 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.

非常感谢马克Gravell。

Many thanks to Marc Gravell.

推荐答案

将在<一个href=\"http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx\">dynamic LINQ库帮助吗?特别是,我想作为一个其中,条款。如果有必要,把它放在一个列表/数组中只是调用。凡(串)就可以了!即。

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();

如果不是,写一个解析器(使用防爆pression 引擎盖下)不是非常繁重 - 我写的一款类似的(虽然我不认为我有源)在我的火车通勤只是圣诞节之前...

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防爆pression树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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