我正在玩LINQPad并且很好奇我如何在我自己的应用程序中实现类似的行为,即:我如何允许用户将已知数据库上下文的LINQ查询作为字符串输入,然后运行该查询申请?
例如,如果我的应用程序中有Northwind数据库的LINQ-to-SQL datacontext,我希望用户能够键入
from cust in Customers
where cust.City == "London"
select cust;
我将返回在此查询中调用.ToList()的结果。
任何想法/提示/链接?
非常感谢
的Mustafa
答案 0 :(得分: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。或者无论如何。
请注意,每次以这种方式编译代码时,您都要创建一个新程序集,然后需要先将其加载到应用程序中,然后才能执行它。装配不是垃圾收集;如果用户想要运行许多查询,可能会导致令人讨厌的内存泄漏。
注意用户可以通过键入他们想要执行的任何恶意代码来进行的攻击也是一个好主意。但我在那里没有任何坚实的建议。
答案 1 :(得分:3)
通过使用.NET Reflector来反汇编可执行文件(LINQPad不是开源),您可以看到LINQPad究竟是如何做到的。他们实际上甚至在许可证中提到它:
您可以自由地反汇编可执行文件以满足您的好奇心。
另外,这将是了解该工具内部工作原理的好方法,并在其代码中找到一些巧妙的技巧。
答案 2 :(得分:1)
我建议您查看“Snippy”的源代码,这是John Skeet的书"C# in depth"中的一个很好的工具。您可以从网站下载它。代码文件“Snippet.cs”只有大约130行代码,并包含动态编译代码的相关部分。
答案 3 :(得分:0)
基本上,我也对这个主题做了一些研究,但不幸的是我没有找到一个或一个很好的例子。在我的代码中,我现在使用这样的解决方案:
这是您的查询:
from cust in Customers
where cust.City == "London"
select cust;
如果你想动态地改变Lquery而不是cust.City ==“London”到cust.Street ==“London”。您应该使用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();
上面的代码比您的代码长,但它可能会满足您的主题。在我的项目中,我仍在使用此代码,因为它不会延迟我的程序,但确实满足了我当前的问题。