2016-03-03 31 views
1

我正在使用EF 7.0.0.0-rc1-final。EF核心1.0:如何查詢整棵樹?

我有一個樹結構,從GrandGrandParent一個一對多的關係,祖父母父到子:

public class GrandGrandParent 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual List<GrandParent> GrandParents { get; set; } 

    public GrandGrandParent() 
    { 
     this.GrandParents = new List<GrandParent>(); 
    } 
} 

public class GrandParent 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual GrandGrandParent GrandGrandParent { get; set; } 
    public virtual List<Parent> Parents { get; set; } 

    public GrandParent() 
    { 
     this.Parents = new List<Parent>(); 
    } 
} 

public class Parent 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual GrandParent GrandParent { get; set; } 
    public virtual List<Child> Children { get; set; } 

    public Parent() 
    { 
     this.Children = new List<Child>(); 
    } 
} 

public class Child 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual Parent Parent { get; set; } 
} 

使用EF核心1.0(EF 7),我怎麼可以創建一個LINQ查詢(或與子查詢),給了我整棵樹,給予一個特定的盛大父母ID?

我可以。包括()上下一層,也許我是明顯的盲目?這給了我GrandGrandParent和GrandParents的列表:

var ggparent1 = from ggp in myDbContext.GrandGrandParent 
       .Include(ggp => ggp.GrandParents) 
       where ggp.ID == 2 
       select ggp; 

我想得到整個樹,下到兒童列表。我必須求助於編寫一個foreach()循環並手動構建樹嗎?

+0

如何設計你的數據庫?你有4桌,2或1?儘管您的層次結構很奇怪,但有多少表格可以指導我們爲您提供幫助(特別是在包含和連接時) – cdie

+0

有4個表格,每個類別一個表格。選擇層次結構是爲了以通用方式顯示我的問題,因此讀者不必費心學習業務邏輯。我試圖對下列LINQ變化: 變種gparents從GP =在myDbContext.GrandParent .INCLUDE(gparent => gparent.GrandGrandParent) .INCLUDE(gparent => gparent.Parents) .ThenInclude(孩子=>兒童.Select(child => child.ID)) 其中gp.GrandGrandParent.ID == 2 select gp;但是。然後包含總是拋出一個異常。 –

+0

什麼是例外? – cdie

回答

2

我只想去與LINQ的形式:

private static void Test0(ApplicationDbContext myDbContext) 
{ 
    var ggparent = myDbContext.GrandGrandParents 
     .Include(ggp => ggp.GrandParents) 
     .ThenInclude(gp => gp.Parents) 
     .ThenInclude(p => p.Children) 
     .FirstOrDefault(ggp => ggp.ID == 3); 

    if (ggparent == null) 
    { 
     DebugPrint("GrandGrandParent not found"); 
     return; 
    } 

    DebugPrint("GrandGrandParent:"); 
    DebugPrint(ggparent); 


    if (ggparent.GrandParents == null) 
    { 
     DebugPrint("GrandParents null"); 
     return; 
    } 

    foreach (var gparent in ggparent.GrandParents) 
    { 
     DebugPrint(gparent); 
     if (gparent.Parents == null) continue; 
     foreach (var parent in gparent.Parents) 
     { 
      DebugPrint(parent); 
      if (parent.Children == null) continue; 
      foreach (var child in parent.Children) 
      { 
       DebugPrint(child); 
      } 
     } 
    } 

    int changeCount = myDbContext.SaveChanges(); 
    DebugPrint(string.Format("ChangeCount={0}", changeCount)); 
} 

那麼你不必由你自己做的子查詢。但是您可以添加日誌記錄以查看EF實際創建的SQL查詢。

如果你需要完整的樹,你不需要select。您可以使用select來提取結果樹的一部分或從層次結構中構建新的(平面)對象。

,我壓扁只有兩個級別的層級(有許多到多)這個例子中的一個分組的SelectList的項目:

var result = 
    (from c in dbContext.EventTypes 
    join j in dbContext.EventType2EventTypes on c.Id equals j.ChildEventTypeId 
    join p in dbContext.EventTypes on j.ParentEventTypeId equals p.Id 
    where p.EventTypeLevel == EventTypeLevel.First && c.EventTypeLevel == EventTypeLevel.Second 
    orderby p.SortOrder, p.Id, c.SortOrder, c.Id 
    select new SelectListItem 
    { 
     Text = c.NameDe, 
     Value = c.Id.ToString(), 
     Group = GetParentEventTypeSelectListGroup(p.NameDe) 
    }).AsNoTracking();