2011-03-23 138 views
10

什麼方法會被認爲是將LINQ字符串解析爲查詢的最佳實踐?將字符串解析爲LINQ查詢

或者換句話說,什麼方法是最有意義的轉換:

string query = @"from element in source 
        where element.Property = ""param"" 
        select element"; 

IEnumerable<Element> = from element in source 
         where element.Property = "param" 
         select element; 

假設sourceIEnumerable<Element>IQueryable<Element>在局部範圍內。

+0

不幸的是,這將是艱難的。我希望有人讓我感到驚訝,並證明我錯了,但我不指望它會發生。 – Jon 2011-03-23 01:52:14

+2

不完全回答你的問題,但非常接近http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library .aspx – 2011-03-23 01:53:52

+2

聽起來像www.linqpad.net會做什麼......但我不知道他們是如何做到的。 – 2011-03-23 02:34:25

回答

0

雖然這並沒有具體舉一個例子來回答你的問題我還以爲最好的做法通常是從字符串構建表達式樹。

this問題我問了如何用一個字符串過濾linq查詢,該字符串顯示您構建表達式樹的一部分。然而,這個概念可以擴展爲構建一個表示你的字符串的整個表達式樹。

Microsoft看到這篇文章。

這裏也可能有其他更好的帖子。此外,我認爲像RavenDB這樣的代碼庫已經在定義索引。

4

它需要一些文本解析和大量使用System.Linq.Expressions。我已經做了一些這個herehere玩弄。第二篇文章中的代碼從第一篇稍微更新,但仍然很粗糙。我有時會繼續混淆,有一些更清晰的版本,如果您有任何興趣,我一直有意發佈。我已經非常接近支持ANSI SQL 89的一個好子集。

2

您將需要一個C#語言解析器(至少v3.5,可能是v4.0,具體取決於您的C#語言功能希望在LINQ中支持)。您將使用這些解析器結果並使用訪問者模式將其直接饋入到表達式樹中。我還不確定,但我敢打賭,你還需要某種形式的分析才能完全生成表達式節點。

我正在尋找和你一樣的東西,但我並不需要那麼嚴重,所以我沒有努力搜索,也沒有寫出任何代碼。

我已經寫了一些東西,需要用戶字符串輸入並使用Microsoft.CSharp.CSharpCodeProvider編譯器提供程序類將其編譯爲動態程序集。如果你只是想要獲得一串代碼並執行結果,這應該適合你。

這裏是控制檯工具,我寫的說明,LinqFilter:

http://bittwiddlers.org/?p=141

這裏的源代碼庫。 LinqFilter/Program.cs中演示瞭如何使用編譯器來編譯LINQ表達式:

http://bittwiddlers.org/viewsvn/trunk/public/LinqFilter/?root=WellDunne

+0

一個想法發生:如果你偏執於字符串必須是表達式,你可以使用'CSharpCodeProvider'並沿'Expression > query =(LINQ CODE HERE)'行生成代碼;'然後你編譯器將爲您創建表達式樹。這只是一個'Compile()'調用的問題,以獲取委託來執行它並通過一些反射來找到您生成的動態程序集的方法,以便您可以執行該方法。希望這是有道理的;我在這裏散步哈哈。 :) – 2011-03-23 03:04:55

+0

請原諒我,它需要是一個'Expression >>或'Expression >>。在您生成的代碼中,您可以安全地連接如下:'Expression >> getQuery =()=>(此處爲linq查詢);'編譯器將只接受可以解析爲表達式樹的有效表達式。對於C#v3.5,這排除了語句和賦值表達式。 – 2011-03-23 03:45:10

+0

要執行查詢,請使用'getQuery'並執行'getQuery.Compile()()'。這兩個括號對在這裏不是一個錯誤。你調用'Compile()'方法,該方法可以讓你返回一個委託,並且調用該委託返回你的'IQueryable '或者你期待的任何IQueryable/IEnumerable類型。 – 2011-03-23 03:46:16

1

與.NET 4.6開始,你可以使用CSharpScript解析的LINQ也,假設你要分析是在查詢表達式,這將做到這一點:

string query = "from element in source where element.Property = ""param"" select element"; 
IEnumerable result = null; 
try 
{ 
    var scriptOptions = ScriptOptions.Default.WithReferences(typeof(System.Linq.Enumerable).Assembly).WithImports("System.Linq"); 
    result = await CSharpScript.EvaluateAsync<IEnumerable>(
      query, 
      scriptOptions, 
      globals: global); 
} catch (CompilationErrorException ex) { 
// 
} 

不要忘記通過你的(數據)來源,您可以使用全局變量從腳本訪問它們。