解析字符串的 C# LINQ 表达式

15

我正在尝试进行一些非常动态的查询 - 最好不要在运行时调用编译器。

我有一个包含LINQ表达式的字符串,例如:

var s = "from a in queryable where a.Type == 1 select a";

我该如何获取生成的IQueryable或表达式呢?

我知道LINQPad和RavenDb都能做到这一点,所以我相信有方法可以实现,只是我还没找到。

2个回答

20

你有一些选项:

  1. 自己编写代码,解析文本并构建表达式树。 标准方法是使用语言解析器来解析字符串(如 ANTLR)。

  2. 使用 CodeDOM 来编译查询(不建议在生产环境中使用,因为这很慢并且每次编译都会生成一个程序集,如果您进行多次编译,将会饱和您的 AppDomain。让我强调一下,如果您有任何量级,请不要选择这条路-尽管这就是 LINQPad 所做的)- http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/6a4defd2-76f0-4865-97b7-130e4ba7b50a

  3. 使用 Mono 的编译器直接发出 MSIL(因此每次编译都没有程序集,速度更快) - Mono Compiler as a Service (MCS)

  4. 使用动态 LINQ(具有一些限制和限制,但基本上执行第 1 点建议的操作,是轻巧且具有仅允许某些方法调用的能力。它解析文本查询并从中构建表达式树) - http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx


1
#1 不切实际。#3 在Microsoft CLR下不起作用(我试过了...)。#4 可以正常工作,但是有一些限制。 - Roman Starkov
我打算尝试第三个,我之前在Miguel de Icaza的博客上读到一篇文章,说Mono.CSharp现在可以在MS CLR上运行。 - Kevin McKelvin
2
数字3在MS Windows CLR下是可用的。我已经尝试过并且正在生产中使用它。如果它给你带来了问题,请查看我的帖子。Kevin,如果你选择数字3,请确保按照我链接的帖子中的说明进行操作,否则你将无法使用LINQ,并且会遇到与CodeDom相同的每次编译问题。 - Jeff
我将此标记为答案,谢谢。我正在努力解决第三个问题 - 实际运行查询并获取IQueryable返回的问题。如果这不起作用,我会退回到第四点。 - Kevin McKelvin
1
我也曾经花了一整天的时间去解决这个问题。但自那以后,它一直运行良好。这是我们当前的生产实现(已经先完成了4、2、1)。 - Jeff

0

从“魔术字符串”到代码对象的转换总是涉及某种解析。在这种情况下,最好使用EditableExpression库(可从Google Code免费获取)。将您的字符串格式化为类似于序列化一系列EditableExpressions的结果。然后,只需反序列化并转换为表达式树即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接