2011-03-23 137 views
10

什么方法会被认为是将LINQ字符串解析为查询的最佳实践?将字符串解析为LINQ查询

或者换句话说,什么方法是最有意义的转换:

string query = @"from element in source 
        where element.Property = ""param"" 
        select element"; 

IEnumerable<Element> = from element in source 
         where element.Property = "param" 
         select element; 

假设sourceIEnumerable<Element>IQueryable<Element>在局部范围内。

+0

不幸的是,这将是艰难的。我希望有人让我感到惊讶,并证明我错了,但我不指望它会发生。 – Jon 2011-03-23 01:52:14

+2

不完全回答你的问题,但非常接近http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library .aspx – 2011-03-23 01:53:52

+2

听起来像www.linqpad.net会做什么......但我不知道他们是如何做到的。 – 2011-03-23 02:34:25

回答

0

虽然这并没有具体举一个例子来回答你的问题我还以为最好的做法通常是从字符串构建表达式树。

this问题我问了如何用一个字符串过滤linq查询,该字符串显示您构建表达式树的一部分。然而,这个概念可以扩展为构建一个表示你的字符串的整个表达式树。

Microsoft看到这篇文章。

这里也可能有其他更好的帖子。此外,我认为像RavenDB这样的代码库已经在定义索引。

4

它需要一些文本解析和大量使用System.Linq.Expressions。我已经做了一些这个herehere玩弄。第二篇文章中的代码从第一篇稍微更新,但仍然很粗糙。我有时会继续混淆,有一些更清晰的版本,如果您有任何兴趣,我一直有意发布。我已经非常接近支持ANSI SQL 89的一个好子集。

2

您将需要一个C#语言解析器(至少v3.5,可能是v4.0,具体取决于您的C#语言功能希望在LINQ中支持)。您将使用这些解析器结果并使用访问者模式将其直接馈入到表达式树中。我还不确定,但我敢打赌,你还需要某种形式的分析才能完全生成表达式节点。

我正在寻找和你一样的东西,但我并不需要那么严重,所以我没有努力搜索,也没有写出任何代码。

我已经写了一些东西,需要用户字符串输入并使用Microsoft.CSharp.CSharpCodeProvider编译器提供程序类将其编译为动态程序集。如果你只是想要获得一串代码并执行结果,这应该适合你。

这里是控制台工具,我写的说明,LinqFilter:

http://bittwiddlers.org/?p=141

这里的源代码库。 LinqFilter/Program.cs中演示了如何使用编译器来编译LINQ表达式:

http://bittwiddlers.org/viewsvn/trunk/public/LinqFilter/?root=WellDunne

+0

一个想法发生:如果你偏执于字符串必须是表达式,你可以使用'CSharpCodeProvider'并沿'Expression > query =(LINQ CODE HERE)'行生成代码;'然后你编译器将为您创建表达式树。这只是一个'Compile()'调用的问题,以获取委托来执行它并通过一些反射来找到您生成的动态程序集的方法,以便您可以执行该方法。希望这是有道理的;我在这里散步哈哈。 :) – 2011-03-23 03:04:55

+0

请原谅我,它需要是一个'Expression >>或'Expression >>。在您生成的代码中,您可以安全地连接如下:'Expression >> getQuery =()=>(此处为linq查询);'编译器将只接受可以解析为表达式树的有效表达式。对于C#v3.5,这排除了语句和赋值表达式。 – 2011-03-23 03:45:10

+0

要执行查询,请使用'getQuery'并执行'getQuery.Compile()()'。这两个括号对在这里不是一个错误。你调用'Compile()'方法,该方法可以让你返回一个委托,并且调用该委托返回你的'IQueryable '或者你期待的任何IQueryable/IEnumerable类型。 – 2011-03-23 03:46:16

1

与.NET 4.6开始,你可以使用CSharpScript解析的LINQ也,假设你要分析是在查询表达式,这将做到这一点:

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) { 
// 
} 

不要忘记通过你的(数据)来源,您可以使用全局变量从脚本访问它们。