簡體   English   中英

Linq將平展表投影到父子對象圖中

[英]Linq projection of flattened table into parent and child object graph

我有一個包含扁平父子關系的可枚舉列表:

ParentGuid1, ParentName1, ChildGuid1, ChildName1
ParentGuid1, ParentName1, ChildGuid2, ChildName2
ParentGuid2, ParentName2, ChildGuid3, ChildName3
ParentGuid2, ParentName2, ChildGuid4, ChildName4

我已經定義了一個Child類和一個包含名為Children的List<Child>屬性的Parent類。

我是否可以使用linq在對象圖上創建每個唯一ParentGuid的一個Parent類實例,引用由與該父級關聯的子項填充的List。

有點像這樣(注意,這段代碼不能編譯):

myFlattenedHierarchy.Select(p => new Parent
   {Guid = p.ParentGuid, 
    Name = p.ParentName, 
    Children = myFlattenedHierarchy.Where(c => c.ParentGuid == p.ParentGuid).Select(c => new Child{Guid = c.ChildGuid, Name = c.ChildName})
   });
myFlattenedHierarchy.Select(p => new Parent
   {Guid = p.ParentGuid, 
    Name = p.ParentName, 
    Children = myFlattenedHierarchy.Where(c => c.ParentGuid == p.ParentGuid).Select(c => new Child{Guid = c.ChildGuid, Name = c.ChildName})
   });

你應該能夠做到這一點,但是Children們不能成為一個列表,它必須是IEnumerable

這是使用簡單循環實現它的前Linq方法。

Dictionary<Guid, Parent> parents = new Dictionary<Guid, Parent>();
foreach(RowType row in myFlattenedHierarchy) //just enumerate once
{
  if (!parents.ContainsKey(row.ParentGuid)
  {
    Parent newParent = new Parent(row);
    parents[row.ParentGuid] = newParent;
  }

  Child newChild = new Child(row);

  Parent theParent = parents[row.ParentGuid];
  theParent.Children.Add(newChild);  
}

List<Parent> result = parents.Values.ToList();

或者您可以使用GroupBy獲得類似的結果。

from row in myFlattenedHierarchy
group row by row.ParentGuid into g
select new Parent()
{
  Guid = g.Key,
  Name = g.First().ParentName,
  Children =
  (
    from childRow in g
    select new Child()
    {
      Guid = childrow.ChildGuid,
      Name = childrow.ChildName
    }
  ).ToList()
}

這是一個更易於維護的折騰。 無論哪種方式,都不要在循環/查詢中重新枚舉myFlattenedHierarchy。

我相信你可以使用GroupBy()(完全披露:未編譯):

myFlattenedHierarchy.GroupBy(row => row.ParentGuid)
    .Select(group => new Parent
        {
            Guid = group.Key.ParentGuid,
            Name = group.Key.ParentName,
            Children = myFlattenedHierarchy.Where(c => c.ParentGuid == group.Key.ParentGuid)
                .Select(c => new Child{ Guid = c.ChildGuid, Name = c.ChildName })
                .ToList()
        });

這應該工作,非常類似於David B的第二個例子但是我無法讓他的工作沒有一點修復(按多列分組)所以我在這里添加它以備記錄。

from row in myFlattenedHierarchy
group row by new { row.ParentGuid, row.ParentName } into g
select new Parent()
{
  Guid = g.Key.ParentGuid,
  Name = g.Key.ParentName,
  Children =
  (
    from childRow in g
    select new Child()
    {
      Guid = childRow.ChildGuid,
      Name = childRow.ChildName
    }
  ).ToList()
};

如果你的扁平集合中有一個循環,你需要處理遞歸和無限遞歸。 Linq不能用於完整的問題,但可以幫助返回特定節點的子節點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM