2010-01-07 134 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(); 

上面的代码比您的代码长,但它可能会满足您的主题。在我的项目中,我仍然使用这个代码,因为它不会延迟我的程序,但确实满足了我目前的问题。