在LINQ防爆pressing递归递归、LINQ、pressing

由网友(胖紙都有小肚孑)分享简介:我写一个LINQ提供一个分层数据源。我觉得最简单的写例子来说明我要如何使用它,然后编码支持那些使用案例来设计我的API。I am writing a LINQ provider to a hierarchal data source. I find it easiest to design my API by wri...

我写一个LINQ提供一个分层数据源。我觉得最简单的写例子来说明我要如何使用它,然后编码支持那些使用案例来设计我的API。

I am writing a LINQ provider to a hierarchal data source. I find it easiest to design my API by writing examples showing how I want to use it, and then coding to support those use cases.

有一件事我有一个简单的/可重用/优雅的方式来EX preSS深查询或递归在LINQ语句的麻烦。换句话说,是什么来区分的最佳方式:

One thing I am having trouble with is an easy/reusable/elegant way to express "deep query" or recursion in a LINQ statement. In other words, what is the best way to distinguish between:

from item in immediate-descendants-of-current-node where ... select item

from item in all-descendants-of-current-node where ... select item

(编辑:请注意没有这些例子上面的必然反映我想要的查询的结构我感兴趣的任何好办法,当然preSS递归/深度)

( please note neither of those examples above necessarily reflect the structure of the query I want. I am interested in any good way to express recursion/depth)

请注意我不问如何以这样一种方式,它允许递归实现这样的供应商,或如何写我的IQueryable或IEnumerable的。我是从一个人写的LINQ查询和利用我的提供商的角度来看问 - 什么是一种直观的方式为他们的前preSS是否要递归或不是

Please note I am not asking how to implement such a provider, or how to write my IQueryable or IEnumerable in such a way that allows recursion. I am asking from the standpoint of a person writing the LINQ query and utilizing my provider - what is an intuitive way for them to express whether they want to recurse or not?

的数据结构类似于典型的文件系统:一个文件夹可以包含子文件夹的集合,和一个夹也可以包含的项的集合。所以myFolder.Folders重新presents所有谁是MyFolder中的直接子文件夹,并myFolder.Items包含立即MyFolder的范围内的所有项目。这里有一个网站层次结构的一个基本的例子,就像文件夹和页面文件系统:

The data structure resembles a typical file system: a folder can contain a collection of subfolders, and a folder can also contain a collection of items. So myFolder.Folders represents all the folders who are immediate children of myFolder, and myFolder.Items contains all the items immediately within myFolder. Here's a basic example of a site hierachy, much like a filesystem with folders and pages:

(F)Products
    (F)Light Trucks
        (F)Z150
            (I)Pictures
            (I)Specs
            (I)Reviews
        (F)Z250
            (I)Pictures
            (I)Specs
            (I)Reviews
        (F)Z350
            (I)Pictures
            (I)Specs
            (I)Reviews
        (I)Splash Page
    (F)Heavy Trucks
    (F)Consumer Vehicles
    (I)Overview

如果我写的:

from item in lightTrucks.Items where item.Title == "Pictures" select item

什么是最直观的方式前preSS意图,查询获得轻型卡车,或只顾眼前的人下的所有项目?最小侵入,最低摩擦的方式向两个目的之间的区别?

What is the most intuitive way to express an intent that the query get all items underneath Light Trucks, or only the immediate ones? The least-intrusive, lowest-friction way to distinguish between the two intents?

我的#1的目标是能够通过把这个LINQ提供给谁拥有LINQ的平均理解,让他们没有给他们写递归lambda表达式教程写两个递归和列表查询其他开发商。给出用法,看起来很不错,我可以C $ $ C反对的人员。

My #1 goal is to be able to turn this LINQ provider over to other developers who have an average understanding of LINQ and allow them to write both recursive and list queries without giving them a tutorial on writing recursive lambdas. Given a usage that looks good, I can code the provider against that.

补充说明:(我真的吮吸沟通这!) - 此LINQ提供程序是外部系统,它不是简单地走的对象图,也没有在这个特定的情况下,做了递归 EX pression 的实际转化为引擎盖下的任何一种真正的递归活动。只是需要一种方法是深的查询和浅一区分开来。

Additional clarification: (I am really sucking at communicating this!) - This LINQ provider is to an external system, it is not simply walking an object graph, nor in this specific case does a recursive expression actually translate into any kind of true recursive activity under the hood. Just need a way to distinguish between a "deep" query and a "shallow" one.

那么,你觉得是EX preSS的最佳方法是什么?或者是有EX $ P $的标准方法pssing它,我已经错过了?

So, what do you think is the best way to express it? Or is there a standard way of expressing it that I've missed out on?

推荐答案

的LINQ处理toxml用于这一优良,有一个XElement.Elements()/。节点()操作来得到直接孩子和XElement.Descendents() / DescendentNodes()操作来获取所有后代。你会认为这是一个例子吗?

Linq-toXml handles this fine, there is an XElement.Elements()/.Nodes() operation to get immediate children, and a XElement.Descendents()/DescendentNodes() operations to get all descendents. Would you consider that as an example?

要总结的LINQ到XML的行为......导航功能分别对应于XPath的轴型(http://www.w3schools.com/xpath/xpath_axes.asp)。如果导航功能选择的元素,所述轴名称被使用。如果导航功能选择节点,轴名称使用节点追加。

To summarize Linq-to-Xml's behavior... The navigation functions each correspond to an axis type in XPath (http://www.w3schools.com/xpath/xpath_axes.asp). If the navigation function selects Elements, the axis name is used. If the navigation function selects Nodes, the axis name is used with Node appended.

例如,有功能的后裔()和DescendantsNode()对应于XPath的后裔轴,要么返回一个的XElement或XNode。

For instance, there are functions Descendants() and DescendantsNode() correspond to XPath's descendants axis, returning either an XElement or an XNode.

例外情况并不出奇最常用的情况下,孩子轴。在XPath中,这是如果没有指定轴使用的轴。为此,LINQ到XML的导航功能是不是儿童()和ChildrenNodes(),而是要素()和节点()。

The exception case is not surprisingly the most used case, the children axis. In XPath, this is the axis used if no axis is specified. For this, the linq-to-xml navigation functions are not Children() and ChildrenNodes() but rather Elements() and Nodes().

的XElement是XNode的子类型。 XNode的包括像HTML标签,但也HTML注释,CDATA或文本。 XElements是一种类型的XNode,但特别提到HTML标签。因此XElements有一个标签名,并支持导航功能。

XElement is a subtype of XNode. XNode's include things like HTML tags, but also HTML comments, cdata or text. XElements are a type of XNode, but refer specifically to HTML tags. XElements therefore have a tag name, and support the navigation functions.

现在它不是以连锁导航在容易Linq到XML作为它的XPath。的问题是,导航功能返回集合对象,而导航功能应用于非集合。考虑的XPath EX pression它选择表标签作为直接子则任何后代表中的数据标签。我认为这会看起来像./children::table/descendants::td或./table/descendants::td

Now its not as easy to chain navigations in Linq-to-XML as it is XPath. The problem is that navigation functions return collection objects, while the navigation functions are applied to non-collections. Consider the XPath expression which selects a table tag as an immediate child then any descendant table data tag. I think this would look like "./children::table/descendants::td" or "./table/descendants::td"

使用了IEnumerable<> ::的SelectMany()允许一个调用导航功能上的集合。相当于上述看起来像.Elements(表)。的SelectMany(T => T.Descendants(TD))

Using IEnumerable<>::SelectMany() allows one to call the navigation functions on a collection. The equivalent to the above looks something like .Elements("table").SelectMany(T => T.Descendants("td"))

阅读全文

相关推荐

最新文章