将条件表达式解析为字符串

时间:2010-11-17 01:57:26

标签: c# linq expression expressionvisitor

我正在寻找一种将条件表达式解析为字符串的方法。

我能想到的最好的例子是LINQ-to-SQL。它使用ExpressionVisitors格式化“Where”子句。例如:

from a in b where a.x == 5 && a.y < 3 select a

那将转换为以下字符串(大约,MSSQL对我来说不是最新的):

"SELECT * FROM b WHERE x = 5 AND y < 3"

根据我的阅读,这是使用ExpressionVisitor类完成的,如本文所述:http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx

现在的问题是我不使用LINQ,但我需要这个特殊的功能。有没有办法解析这样的条件?我愿意用反思,代表,lambda等做任何事情。

老实说,我不认为这是可能的,但是我的大脑有点油腻(读:如果这个问题很荒谬,那就好了),所以我想我也可以给S /试一试。

编辑:最终用法示例:

// Usage:
foo.Bar(foo => foo.X == 5 && foo.Y < 3)

// Ideal string output (variable name (foo) is not needed):
"foo.X == 5 && foo.Y < 3"

编辑2 :是的,一个数字可以低于3,等于5.告诉你我的大脑是油炸的。

2 个答案:

答案 0 :(得分:4)

如果它是关于构建表达式树本身,那么你可以利用C#编译器能力。

只要知道Func的类型参数,将lambda表达式传递给函数接受和表达式&gt;是合法的。例如

 private static void PrintExpression(Expression<Func<int, bool>> lambda)
 {
      Console.WriteLine(lambda.ToString());
 }

可以称为

 PrintExpression(a=> a > 0 && a < 5);

您可以使用泛型即兴创作

private static void PrintExpression<T1,T2>(Expression<Func<T1, T2>> lambda)
{
      Console.WriteLine(lambda.ToString());
}

并用

调用它
   PrintExpression<int, bool>(a=> a > 0 && a < 5);

对于表达式部分的自定义打印,您可以编写一个简单的递归函数来打印表达式或任何其他适合您的逻辑。

请记住,lambda表达式在编译时被编译成一个Expression - 所以不能用已编译的Func替换它。

作为替代方案,您始终可以构建自定义查询提供程序,但这会略微偏离目的 - 因为您需要将其绑定到某种可查询状态(再次自定义)。

答案 1 :(得分:3)

尝试这样的事情:

static string GetExpressionString<T>(Expression<Func<T, bool>> expression)
{
    return expression.Body.ToString();
}

用法如下:

string s = GetExpressionString<Foo>(foo => foo.X == 5 && foo.Y < 3);

将返回:

((foo.X = 5) && (foo.Y < 3))