Reputation: 740
I was playing around with LINQPad and was curious how I could implement similar behavior in my own app, namely: how can I allow the user to input a LINQ query against a known database context as a string and then run that query in the application?
For example, if I have the LINQ-to-SQL datacontext for the Northwind database in my application, I want the user to have the ability to type
from cust in Customers
where cust.City == "London"
select cust;
And I'll return the results of calling .ToList() on this query.
Any ideas/tips/links?
Thanks kindly
Mustafa
Upvotes: 3
Views: 2338
Reputation: 959
Basically, I am also do some research on this topic but unfortunately I haven't found one or a good example for this. In my code, I am now using a solution like this:
This is your query:
from cust in Customers
where cust.City == "London"
select cust;
If you want to dynamically change the Lquery like instead of cust.City == "London" to cust.Street == "London". You should use an if-else statement like this:
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();
The code above is longer than your code, but it may satisfy your topic. In my project, I am still using this code because it doesn't delay my program but does satisfy my current problem.
Upvotes: 0
Reputation: 11487
The System.CodeDom
namespace might do what you're looking for. Check out this blog post:
http://blogs.msdn.com/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx
Though instead of public static void Main
you could compile a static method that takes a DataContext class and returns IEnumerable using the provided LINQ query. Or whatever works.
Be mindful that everytime you compile code this way you're creating a new assembly, which would then need to be loaded into your application before you can execute it. Assemblies aren't garbage collected; if users are going to want to run many, many queries it could lead to a nasty memory leak.
And it'd also be a good idea to be mindful of possible attacks users can do by typing in whatever malicious code they want executed. But I don't have any rock solid advice for you there.
Upvotes: 4
Reputation: 20044
I suggest having a look into the source code of "Snippy", a nice tool from John Skeet's book "C# in depth". You can download it from the web site. The code file "Snippet.cs" has only about 130 lines of code and contains the relevant parts for compiling code on the fly.
Upvotes: 1
Reputation: 8966
You could see exactly how LINQPad does it by using .NET Reflector to disassemble the executable (LINQPad isn't open source). They actually even mention it in their license:
You are free to disassemble the executable to satisfy your curiosity.
Plus, this would be a great way to learn the inner workings of the tool, and find some neat tricks in their code.
Upvotes: 3