Parse string into a LINQ query
What method would be considered best practice for parsing a LINQ string into a query?
Or in other words, what approach makes the most sense to convert:
string query = @"from element in source
where element.Property = ""param""
select elemen开发者_Go百科t";
into
IEnumerable<Element> = from element in source
where element.Property = "param"
select element;
assuming that source
refers to an IEnumerable<Element>
or IQueryable<Element>
in the local scope.
Starting with .NET 4.6 you can use CSharpScript to parse Linq. Assuming the expression you want to parse is in string variable "query", this will do it:
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) {
//
}
Don't forget to pass your (Data)source you want to work on, with the global-variable(s) to have access to them in script parsing.
It requires some text parsing and heavy use of System.Linq.Expressions. I've done some toying with this here and here. The code in the second article is somewhat updated from the first but still rough in spots. I've continued to mess round with this on occasion and have a somewhat cleaner version that I've been meaning to post if you have any interest. I've got it pretty close to supporting a good subset of ANSI SQL 89.
You're going to need a C# language parser (at least v3.5, possibly v4.0, depending on what C# language features you wish to support in LINQ). You'll take those parser results and feed it directly into an Expression tree using a visitor pattern. I'm not sure yet but I'm willing to bet you'll also need some form of type analysis to fully generate the Expression nodes.
I'm looking for the same thing as you, but I don't really need it that badly so I haven't searched hard nor written any code along these lines.
I have written something that takes user string input and compiles it to a dynamic assembly using the Microsoft.CSharp.CSharpCodeProvider
compiler provider class. If you just want to take strings of code and execute the result, this should suit you fine.
Here's the description of the console tool I wrote, LinqFilter:
http://bittwiddlers.org/?p=141
Here's the source repository. LinqFilter/Program.cs demonstrates how to use the compiler to compile the LINQ expression:
http://bittwiddlers.org/viewsvn/trunk/public/LinqFilter/?root=WellDunne
This might work for you: C# eval equivalent?
This may or may not help you, but check out LINQ Dynamic Query Library.
While this doesn't specifically give an example to answer your question I would have thought the best practice would generally be to build an expression tree from the string.
In this question I asked how to filter a linq query with a string which shows you building a portion of an expression tree. This concept however can be extended to build an entire expression tree representing your string.
See this article from Microsoft.
There are probably other better posts out there as well. Additionally I think something like RavenDB does this already in its code base for defining indexes.
精彩评论