2010-01-07 203 views
3

我在玩弄LINQPad,很好奇我如何在自己的應用中實現類似的行爲,即:我如何允許用戶輸入對已知數據庫上下文的LINQ查詢作爲字符串,然後在應用程序中運行該查詢?將字符串轉換爲linq查詢

舉例來說,如果我有LINQ到SQL的DataContext在我的應用程序的Northwind數據庫,我希望用戶必須鍵入

from cust in Customers 
where cust.City == "London" 
select cust; 

的能力,我會返回的結果在此查詢上調用.ToList()。

任何想法/提示/鏈接?

感謝好心

穆斯塔法

回答

4

命名空間System.CodeDom可能會做你正在尋找。看看這個博客帖子:

http://blogs.msdn.com/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx

雖然不是public static void Main你可以編譯,需要一個DataContext類,並使用所提供的LINQ查詢返回的IEnumerable的靜態方法。或者任何作品。

請注意,您每次以這種方式編譯代碼時,都會創建一個新程序集,然後在執行它之前需要將其裝入您的應用程序。組件不是垃圾收集;如果用戶想要運行很多很多的查詢,它可能會導致令人討厭的內存泄漏。

而且用戶可以通過輸入他們想要執行的任何惡意代碼來防止可能的攻擊,這也是一個好主意。但是我沒有給你任何堅定的建議。

+0

任何想法,如果這在中等信託運行?因爲我非常肯定我必須部署到這樣的環境,所以只是想着未來。 此外,任何線索如何嚴重影響性能與以某種方式使用反射(這是我如何隱約想我會解決這個問題) – Mustafakidd 2010-01-08 23:15:31

3

你可以看到通過使用.NET反射拆解可執行LINQPad究竟是如何做它(LINQPad是不是開源的)。他們實際上甚至提到在他們的許可:

您可以自由拆卸可執行滿足你的好奇心。

此外,這將是一個很好的方式來學習工具的內部工作,並找到一些巧妙的技巧在他們的代碼。

1

我建議看一看「Snippy」的源代碼,這是John Skeet的書"C# in depth"的一個很好的工具。您可以從網站下載它。代碼文件「Snippet.cs」只有大約130行代碼,包含用於編譯代碼的相關部分。

0

基本上,我也做了一些關於這個話題的研究,但不幸的是我沒有找到一個或一個很好的例子。在我的代碼,我現在用這樣一個解決方案:

這是您的查詢:

from cust in Customers 
where cust.City == "London" 
select cust; 

如果要動態地改變Lquery等代替cust.City ==「倫敦」,以卡斯特.Street ==「倫敦」。您應該使用如下這樣的if-else語句:

var lquery = (from cust in Customers 
where cust.City == "London" 
select cust).ToList(); 

if(true){ 
lquery = (from cust in Customers 
where cust.Street == "London" 
select cust).ToList(); 
} 

GridView.DataSource = lquery; 
GridView.Databind(); 

上面的代碼比您的代碼長,但它可能會滿足您的主題。在我的項目中,我仍然使用這個代碼,因爲它不會延遲我的程序,但確實滿足了我目前的問題。