Using LINQ to flatten a hierarchical dataset - with a caveat
I have the following dataset I need to flatten into a list:
<row itemID="828518871" locationID="60004165" typeID="9331" quantity="6" flag="4" singleton="0"/>
<row itemID="830476364" locationID="60004165" typeID="649" quantity="1" flag="4" singleton="1">
<rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton">
<row itemID="1139985051" typeID="6485" quantity="1" flag="22" singleton="1"/>
<row itemID="1773489170" typeID="11489" quantity="1" flag="5" singleton="1">
<rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton">
<row itemID="1001694072954" typeID="16357" quantity="1" flag="0" singleton="0"/>
<row itemID="1001694110421" typeID="16371" quantity="1" flag="0" singleton="0"/>
...
</rowset>
</row>
</rowset>
</row>
(...
indicates additional rows and/or levels of nesting; the levels can theoretically nest infinitely.)
The output needs to look like this:
Item { ID = 828518871, Location = 60004165, Type = 9331, Quantity = 6, Flag = 4, Singleton = false }
Item { ID = 830476364, Location = 60004165, Type = 649, Quantity = 1, Flag = 4, Singleton = true }
Item { ID = 1139985051, Location = 60004165, Type = 6开发者_StackOverflow中文版485, Quantity = 1, Flag = 22, Singleton = true }
Item { ID = 1773489170, Location = 60004165, Type = 11489, Quantity = 1, Flag = 5, Singleton = true }
Item { ID = 1001694072954, Location = 60004165, Type = 16357, Quantity = 1, Flag = 0, Singleton = false }
Item { ID = 1001694110421, Location = 60004165, Type = 16371, Quantity = 1, Flag = 0, Singleton = false }
...
The catch is that all rows in the output need to have their LocationID
correctly set - child rows must get this property from their parent, or their parent's parent, etc.
I've written a recursive method that correctly generates the required output, but I would love to get the same results using only LINQ - is this possible?
LINQ isn't generally good with arbitrary recursion. It's fine for flattening one layer of nesting using SelectMany
, but recursive solutions will still end up needing to call themselves explicitly. For example, you can write a method which uses LINQ and which calls itself within the query, but you can't easily make LINQ perform the recursion implicitly.
So you may be able to tweak your existing recursive method to use LINQ, but you're unlikely to end up with a completely different structure to the solution.
I wrote a small extension method called SelectRecursive
to the IEnumerable<T>
interface some time ago that you can use to create recursive linq queries.
http://www.codeproject.com/Tips/80746/Select-Recursive-Extension-method.aspx
精彩评论