#c# #linq
#c# #linq
Вопрос:
У меня есть следующий набор данных, который мне нужно преобразовать в список:
<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>
( ...
указывает дополнительные строки и / или уровни вложенности; уровни теоретически могут вкладываться бесконечно.)
Вывод должен выглядеть следующим образом:
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 = 6485, 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 }
...
Загвоздка в том, что все строки в выходных данных должны быть LocationID
правильно установлены — дочерние строки должны получать это свойство от своего родителя или родительского элемента своего родителя и т.д.
Я написал рекурсивный метод, который корректно генерирует требуемый вывод, но я хотел бы получить те же результаты, используя только LINQ — возможно ли это?
Ответ №1:
LINQ обычно не подходит для произвольной рекурсии. Это прекрасно подходит для выравнивания одного уровня вложенности с помощью SelectMany
, но рекурсивным решениям все равно в конечном итоге потребуется вызывать себя явно. Например, вы можете написать метод, который использует LINQ и который вызывает сам себя в запросе, но вы не можете легко заставить LINQ выполнять рекурсию неявно.
Таким образом, вы можете настроить свой существующий рекурсивный метод для использования LINQ, но вы вряд ли получите структуру, полностью отличающуюся от решения.
Ответ №2:
Некоторое время назад я написал небольшой метод расширения, вызываемый SelectRecursive
для IEnumerable<T>
интерфейса, который вы можете использовать для создания рекурсивных запросов linq. http://www.codeproject.com/Tips/80746/Select-Recursive-Extension-method.aspx