2010-09-23 81 views
15

我想在這裏做一些真正的動態查詢 - 最好不要在運行時調用編譯器。解析字符串C#LINQ表達式

我有一個包含LINQ表達式的字符串,例如,

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

如何從中得到IQueryable或表達式?

我見過LINQPad和RavenDb都這樣做,所以我堅信有一種方法,我只是還沒有找到它。

回答

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工作正常,但是,它具有侷限性。 – 2010-09-23 21:32:36

+0

我打算嘗試#3,我前一段時間在Miguel de Icaza的博客上看過一篇文章,Mono.CSharp現在可以在MS CLR上使用。 – 2010-09-23 21:35:46

+2

3號在MS Windows CLR下工作。試過了,目前正在生產中使用它。如果它給你的專業人員檢查我的文章。凱文,如果你使用數字3,請確保你遵循我鏈接到的文章中的指示,否則你將無法使用LINQ,並且最終會出現與CodeDom相同的每個編譯問題的程序集。 – Jeff 2010-09-23 22:58:14

0

從「魔術字符串」將代碼對象總是需要某種解析。在這種情況下,最好使用EditableExpression庫(可從Google Code免費獲得)。把你的字符串,並格式化看起來像序列化一系列EditableExpressions的結果。然後,將其反序列化並轉換爲表達式樹。

+0

爲什麼那些倒票? – 2013-04-18 14:15:07