Во-первых, для компиляции кода вы можете заменить параметр p => p
в GroupJoin
на p => p.Attribute(XId).Value
, который выбирает ключ для сравнения.
В результате вы получите IEnumerableс объектами
- ParentID = 0,
IEnumerable<XElement>
{Идентификатор строки = 1, Идентификатор строки = 2} - Идентификатор строки = 3,
IEnumerable<XElement>
{Идентификатор строки = 4}
Конечно, вы также можете изменить .Select(c => c)
, чтобы он возвращал List<string>
только с идентификаторами (.Select(c => c.Attribute(XId).Value).ToList()
), но вам все еще не хватает ParentID = -1 иу вас нет словаря.
Если вы хотите включить ParentID = -1, а также получить Dictionary<string,List<string>>
, то вы можете попробовать это (в качестве точки для начала), которая используетдругой подход:
// get all ParentIds
var allParentIds = xData.Elements(XName.Get("Row"))
.Select(e => e.Attribute(XParentId).Value)
.Distinct();
// then use them to get all Ids where the ParentId is in the "list" of all ParentIds
var parentIdsAndChilds = from givenIds
in allParentIds
select new {
Id = givenIds,
Childs = xData.Elements(XName.Get("Row")).Where(e => e.Attribute(XParentId).Value == givenIds).Select(e => e.Attribute(XId).Value).ToList()
};
// if needed, convert it to a Dictionary
Dictionary<string, List<string>> dict = parentIdsAndChilds.ToDictionary(k => k.Id, v => v.Childs);
Надеюсь, это поможет или, может быть, послужит отправной точкой для дальнейших исследований.
Примечание с одной стороны: как вы, возможно, знаете, LINQ использует отложенное выполнение , поэтому вы не можете вызывать ToList()
на каждом шаге, чтобы сэкономить время выполнения (в зависимости от общего объема данных, это может быть хорошей идеейo время от времени использовать ToList()
, потому что это может сэкономить память во время обработки, но это зависит от реальных данных.