【问题标题】:How do I get the query text of the IQueryable<T> instance on which this operator is called?如何获取调用此运算符的 IQueryable<T> 实例的查询文本?
【发布时间】:2015-01-16 16:20:26
【问题描述】:

为此实现提供程序并不难:

var query = from foo in someContext.Foos
                   where foo.Bar == "bar" && foo.Gaz > 4
                   select foo;

但如果我像这样将两个运算符链接在一起:

var chained1 = (from foo in someContext.Foos
                         where foo.Bar == "bar"
                         select foo)
                         .Where(f => f.Gaz > 4);

或者如果我这样做了:

var chained2 = chained1.Take(10);

我将如何实现这个?

在评估当前方法调用或运算符时,在VisitMethodCall 中,我访问了进行方法调用的实例/对象/表达式。这应该调用VisitConstant 来评估/翻译/重写该实例表达式。

然后,如果我这样做,在VisitConstant 中:

if (typeof(IQueryable).IsAssignableFrom(node.Type))
{
    _builder.Append((node.Value as IQueryable).ToString());
}

它不起作用。

如何获取先前构建的查询的查询文本?

【问题讨论】:

  • 无论你使用查询语法还是方法语法,或者在后续操作被调用之前操作是否存储在中间变量中,都对最终的@987654328有字面上的影响@.
  • 您能补充一下somecontext 的创建方式吗?
  • 如何实现查询提供程序将完全取决于您创建提供程序的目的、您希望它如何工作、您希望支持哪些操作、您希望各种 LINQ 操作如何翻译成那种语言等等。事实上,这个问题还远远没有答案。
  • @Servy:虽然你说的有些正确,但要翻译查询的目标/目标 DSL 的细节与这个问题完全不相关。如果没有这些知识,这个问题很容易回答。无论目标 DSL 是什么,实现提供者的总和和实质都是相同的。
  • @WaterCoolrv2 不……不是。如果不知道关于您的查询提供程序还在做什么以及您究竟希望它做什么的大量 信息,这个问题是完全无法回答的。如果您实际上包含所有这些信息,它几乎肯定会使问题变得过于广泛。 IQueryable 几乎可以做任何事情,因为它只限制公共 API;如果您向我们展示了您的实现,我们只能开始讨论为什么您的实现没有做您希望它做的事情。

标签: c# .net linq linq-expressions custom-linq-providers


【解决方案1】:

这是一个很好的系列,可以让你继续前进:http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx

在您的示例中,这是一个伪代码应该做什么(对于您的 Take 示例):

VisitMethodCallExpression 使用 Take 方法调用表达式,您必须这样做:

_sb.Append("SELECT * FROM (");
Visit(..chained1..); // generate query for chained1 to _sb (recursively)
_sb.Append(") LIMIT "); 
VisitConstant(TakeMethodInfo.LambdaExpression);

如您所见,这会起作用,但会导致多余的子查询。你可以在这里阅读更多关于这些的信息:http://blogs.msdn.com/b/mattwar/archive/2008/01/16/linq-building-an-iqueryable-provider-part-ix.aspx

祝你好运。

【讨论】:

  • 谢谢,克里斯。在过去的一年中,我浏览了 Matt 的整个系列,并练习甚至编写了一个自定义 LINQ 提供程序。我无法表达我的问题,如果没有我没有提供的信息,它可能不会很清楚。我实际上在思考,我认为更多思考将帮助我达到我所追求的解决方案。我想我快到了。一旦我想到了我自己的问题,我应该发布一个答案。
  • 我非常感谢您的帮助。 :-)
猜你喜欢
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 2011-10-09
相关资源
最近更新 更多